In my software I'm trying to create a class that returns any bit of an xml file, take a look at the code and the error its giving me, i cant figure out how to correct it :(
Xml :
<everConfigured>
<value>false</value>
</everConfigured>
<ServerPort>
<value>9000</value>
</ServerPort>
<ClientPort>
<value>8000</value>
</ClientPort>
XML Reader Class :
public static String getValue(String Path,String Tag,String Atribute) throws IOException, SAXException, ParserConfigurationException
{
File fXmlFile = new File(Path);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName(Tag);
Node nNode = nList.item(0);
Element eElement = (Element) nNode;
return eElement.getAttribute(Atribute);
}
And here is how I called it :
public static void main(String[] args) throws SocketException, IOException, SAXException, ParserConfigurationException {
System.out.println(
XMLRead.getValue("/home/ghhwer/Desktop/settings.xml", "everConfigured","value"));
}
but returns this error :
[Fatal Error] settings.xml:5:2: The markup in the document following the root element must be well-formed.
Exception in thread "main" org.xml.sax.SAXParseException; systemId: file:/home/ghhwer/Desktop/settings.xml; lineNumber: 5; columnNumber: 2; The markup in the document following the root element must be well-formed.
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:257)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:348)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:205)
at program.XMLRead.getValue(XMLRead.java:20)
at program.Start.main(Start.java:12)
The markup in the document following the root element must be well-formed.
There are several rules for XML to be well-formed:
All XML Elements Must Have a Closing Tag;
Tags should be in the same case;
XML Elements Must be Properly Nested;
XML Documents Must Have a Root Element;
XML Attribute Values Must be Quoted;
Some symbols have special meaning and have to be escaped (>, <, &, ', ").
In provided XML snippet root element is missing, that is why parser complains.
So, well-formed XML will be:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<everConfigured>
<value>false</value>
</everConfigured>
<ServerPort>
<value>9000</value>
</ServerPort>
<ClientPort>
<value>8000</value>
</ClientPort>
</config>
See http://www.w3schools.com/xml/xml_syntax.asp as XML syntax reference.
I think the problem is that in XML there can be only one root element, but you have three.
You have to restructure you file to something like:
<?xml version="1.0" encoding="UTF-8"?>
<OneRootElement>
<everConfigured>
<value>false</value>
</everConfigured>
<ServerPort>
<value>9000</value>
</ServerPort>
<ClientPort>
<value>8000</value>
</ClientPort>
</oneRootElement>
The error about well-formed XML on the root level should disappear
The problem is an XML validation error, to fix it run the file through an online validation tool like http://www.xmlvalidation.com/ or validate it using the IDE.
The tool will pinpoint the cause better, in this case it seems to be a problem of not well formed XML.
Related
I have this XML code:
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="https://www.cvlkra.com/">tTKyEndh0iBqnZdjpUntEQ%3d%3d</string>
I want to get this: tTKyEndh0iBqnZdjpUntEQ%3d%3d for which I have tried the below code:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder1 = factory.newDocumentBuilder();
Document document = builder1.parse(new InputSource(new StringReader(string)));
Element rootElement = document.getDocumentElement();
String nodeName = rootElement.getNodeName();
But i am not getting it. I am getting null value instead of tTKyEndh0iBqnZdjpUntEQ%3d%3d even when I have tried some other code also.
Try using getTextContent() instead getNodeValue() returns null because it has no values.
You should not use getNodeName() instead use rootElement.getNodeValue(). May be this helps.
I have the following XML document which I'm trying to get the inner text. I have tried numerous ways, using Xpath, DOM, SAX but no success.
This is my XML, I'm not sure if it's the XML structure which is causing a problem or my code.
<?xml version="1.0"?>
<ArrayOfPurchaseEntitites xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema">
<PurchaseEntitites>
<rInstalmentAmt>634.0</rInstalmentAmt>
<rAnnualRate>12.0</rAnnualRate>
<rInterestAmt>2670.0</rInterestAmt>
<dFirstInstalment>3/31/2016 12:00:00 AM</dFirstInstalment>
<dLastInstalment>8/31/2018 12:00:00 AM</dLastInstalment>
<rInsurancePremium>1350.0</rInsurancePremium>
<sResponseCode>00</sResponseCode>
</PurchaseEntitites>
</ArrayOfPurchaseEntitites>
InputStream stream = connect.getInputStream();
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document doc = documentBuilder.parse(stream);
doc.normalize();
System.out.println("===============================================================");
String g = doc.getDocumentElement().getTextContent();
System.out.println(g);
NodeList rootNodes = doc.getElementsByTagName("ArrayOfPurchaseEntitites");
Node rootnode =rootNodes.item(0);
Element rootElement = (Element) rootnode;
NodeList noteslist = rootElement.getElementsByTagName("PurchaseEntitites");
for(int i = 0; i < noteslist.getLength(); i++)
{
Node theNote = noteslist.item(i);
Element noteElement =(Element) theNote;
Node theExpiryDate = noteElement.getElementsByTagName("dLastInstalment").item(0);
Element dateElement = (Element) theExpiryDate;
System.out.println(dateElement.getTextContent());
}
stream.close();
I had a similar problem where I wanted to call getElementsByTagName for the first item in a NodeList. The trick - which you already utilize - is to cast the Node to Element. However, just to be sure, I suggest you add if (rootnode instanceof Element).
Assuming you use packages javax.xml.parsers and org.w3c.dom (no wild guess) your code works nicely when the xml is read from a file.
So if there still a problem with the code (it's been a while since this question was asked) I suggest you update the question with more info regarding connect.getInputStream();.
I am using this function :
public void testing(String xml) throws ParserConfigurationException, SAXException, IOException{
Log.d("TAG"," root.getNodeName()");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xml);
//document.getDocumentElement().normalize();
//Element root = document.getDocumentElement();
//Log.d("TAG", root.getNodeName());
Log.d("TAG"," root.getNodeName()");
}
And I am calling this function like this :
testing(responseText)
Where response text is this:
<?xml version='1.0' encoding='UTF-8'?>
<queryresult success='true'
error='false'
numpods='2'
datatypes=''
timedout=''
timedoutpods=''
timing='0.751'
parsetiming='0.216'
parsetimedout='false'
recalculate='http://www4b.wolframalpha.com/api/v2/recalc.jsp?id=MSPa2715236aaf6db55age00000025hbhc18c61h80c4&s=10'
id='MSPa2716236aaf6db55age00000019f566b957ic219h'
host='http://www4b.wolframalpha.com'
server='10'
related='http://www4b.wolframalpha.com/api/v2/relatedQueries.jsp?id=MSPa2717236aaf6db55age000000535a701459c5c90a&s=10'
version='2.6'>
<pod title='Input interpretation'
scanner='Identity'
id='Input'
position='100'
error='false'
numsubpods='1'>
<subpod title=''>
<plaintext>Tell me a joke.</plaintext>
</subpod>
</pod>
<pod title='Result'
scanner='Data'
id='Result'
position='200'
But im getting the error:
04-06 22:19:14.348: D/TAG(30413): java.net.MalformedURLException:
Protocol not found:
What am I doing wrong ?
Note that I am getting this responseText from a server. So if theres any problem with the xml itself, do tell me how to manipulate the string, instead of suggesting me to change the xml itself.
The problem is that you're passing in the XML content itself - but DocumentBuilder.parse(String) accepts a URL to load the XML from - not the content itself.
You probably want to use DocumentBuilder.parse(InputSource) instead, having created an InputSource from a StringReader wrapping the XML:
Document document = builder.parse(new InputSource(new StringReader(xml)));
I've written a program to read a set of source files and convert them into XML files using SrcML tool. Basically the procedure as follows.
for (------------------) {
-------------------
String xmlUri = GetXmlFile(sourceFileUri); // create xml file and get its uri
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlUri);
-------------------
}
For each source file the program creates a XML file in the same location (by overriding the previously created file) and read the XML file. For some source files this procedure works fine. But most of them it gives some SAX Parse Exceptions as follows:
Premature end of file.
Content is not allowed in prolog.
The element type "argcl" must be terminated by the matching end-tag "". (this XML file doesn't even contains an element by name "argcl"
XML document structures must start and end within the same entity.
The SrcML tool creates valid XML documents. When I check the XML file for some of these exception it doesn't show anything wrong with the format.
All exceptions pointed out to the same line in the code which is:
"Document doc = dBuilder.parse(xmlUri);"
I have gone through number of discussions related to this topic in stack over flow as well as in other forums. Neither provides me a clue to overcome this problem.
I really appreciate if someone can help me to solve this problem.
Thank you.
Here's the source code written to read XML file:
private static Document GetXmlDom(String xmlFilePath)
throws SAXException, ParserConfigurationException, IOException {
File tempFile;
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFilePath);
if (doc.hasChildNodes()) {
return doc;
}
}
catch (IOException e) {
e.printStackTrace();
throw e;
}
catch (SAXParseException e) {
e.printStackTrace();
throw e;
}
return null;
}
private static String GetXmlFile(String inputFile) throws IOException {
if (new File(inputFile).isFile()) {
String outFile = FileNameHandler.GetNextNumberedFileName(FileNameHandler.getXmlFlePath(), "outFile.xml");
Process process = new ProcessBuilder("srcML\\src2srcml.exe", inputFile,
"-o", outFile).start();
return outFile;
}
else {
System.out.println("\nNo XML file is created. File does not exist: " + inputFile);
}
return null;
}
public static List<Tag> SourceToXML(String inputFile)
throws SAXException, ParserConfigurationException, IOException {
List<Tag> tagList = new LinkedList<Tag>();
String xmlUri = GetXmlFile(inputFile);
Document doc = GetXmlDom(xmlUri);
if (doc != null) {
LinkedList<Integer> id = new LinkedList<Integer>();
id.add(1);
TagHierarchy.CreateStructuredDom(new TagId(id), doc.getFirstChild(), tagList);
tagList.get(0).setAncestor(null);
TagHierarchy.SetTagHierarchy(tagList);
}
return tagList;
}
Here's the exception thrown:
[Fatal Error] outFile.xml:461:300: The element type "argcl" must be
terminated by the matching end-tag "".
org.xml.sax.SAXParseException; systemId:
file:/E:/srcML/Output/outFile.xml; lineNumber: 461; columnNumber: 300;
The element type "argcl" must be terminated by the matching end-tag
"". at
com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown
Source) at
com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown
Source) at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
at vocab.util.file.FileConverter.SourceToXML(FileConverter.java:188)
at vocab.CodeVocabulary.Create(CodeVocabulary.java:59) at
vocab.CodeVocabulary.(CodeVocabulary.java:53) at
vocab.util.DataAcccessUtil.GetCodeVocabularies(DataAcccessUtil.java:331)
at vocab.TestMain.main(TestMain.java:57)
It seems like you're starting a process which generates an XML file, and read the generated file directly after. This means that the parser will read the file while the process is running and writing to the same file. So the parser will not see the complete generated file.
You should wait for the process to finish before reading the file it generates.
You should also respect the Java naming conventions: methods start with a lowercase letter.
I'm trying to read the comments in an XML file. Not able to get the comment nodes after parsing it with DOM.
Code:
DocumentBuilderFactory docBldrFactry = DocumentBuilderFactory.newInstance();
docBldrFactry.setIgnoringComments(false);
DocumentBuilder docBuilder = docBldrFactry.newDocumentBuilder();
Document document = docBuilder.parse(new File("C:\\webser.xml"));
Element rootElement = document.getDocumentElement();
NodeList list = rootElement.getElementsByTagName("Bean");
Comments are under Bean element. WHen I loop through the child nodes of Bean element, I don't get the comment nodes.
Here is the XML
<Beans>
<Bean>
<!-- Testing Comments -->
<API name ="xyz" />
</Bean>
</Beans>
Hope this helps :)
XMLStreamReader xr = XMLInputFactory.newInstance().createXMLStreamReader(new FileInputStream("file.xml"));
while (xr.hasNext()) {
if (xr.next() == XMLStreamConstants.COMMENT) {
String comment = xr.getText();
} }