This question already has answers here:
Java DOM getElementByID
(2 answers)
Closed 3 years ago.
I have an xml document being parsed in Java as a w3c document.
In my xml, i have many elements of the same name, e.g <item ..... />, each one with unique attribute's value, e.g <item name="a" .... />.
I want in java to do:
doc.getElementById("a")
in order to get that specific item I have there with that name.
How can I tell java to use 'name' as the id?
Or, alternately, How can I fetch that specific item in least complexity?
DOM is not the best API to easily query your document and get back found elements. Learn XPath, which is a more appropriate API, or iterate through the tree of elements by yourself.
getElementById() will only return the element which has the given id attribute (edit: marked as such in the document DTD or schema). It can't find by name attribute.
See Java XML DOM: how are id Attributes special? for details.
You need to write a DTD that defines your attribute as being of type ID.
Well, To make a complete answer, I had to use DTD schemas like everyone stated.
Since my needs are quite simple, I added it in embedded in my xml the following way:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ATTLIST item
name ID #REQUIRED
>
]>
<root> .... </root>
The only important thing left to know is that once you declare the ATTLIST, I have to declare all of the rest of my attributes, therefore, you need to add IMPLIED:
some-attribute CDATA #IMPLIED
It says that some-attribute contains some data (can use also PCDATA for parsed cdata), and is implied, which means, it can be there or it cannot. doesnt matter.
So eventually, it'll look something like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ATTLIST item
name ID #REQUIRED
some-attribute CDATA #IMPLIED
>
]>
<root> .... </root>
And from Java side, Just use it blindly, e.g getElementById("some-name")
In order to make doc.getElementById("a") work you need to change your XML to <item id="a" name="a" .... />
If you can't change the XML, you could use XPath to retrieve this element.
Related
My Project Manager told me to move all the queries in a xml file (he even made for me), so when the user (via jsp) select the description: "Flusso VLT mensile" he has 2 options, click search, update or download, (the download it works now but I need to get the name of filename), he told me to work with jaxb but I don't think is necessary
<flow-monitor>
<menu1>
<item id="7" type="simple">
<connection name="VALSAP" />
<description value="Flusso VLT mensile" />
<filename value="flussoVltmensile" />
<select><![CDATA[
SELECT * FROM vlt_sap WHERE stato=7
]]>
</select>
<update>
<![CDATA[update vlt_sap set stato = 0 where stato =7]]>
</update>
</item>
<item id="11" type="simple">
<connection name="VALSAP" />
<description value="Flusso REPNORM BERSANI" />
<filename value="flussoRepnormBersani" />
<select><![CDATA[
select * from repnorm_bersani_sap where stato = 99
]]>
</select>
<update>
<![CDATA[update repnorm_bersani_sap set stato=0 where stato = 99]]>
</update>
</item>
</menu1>
</flow-monitor>
On java I should read this xml and depending on <description value=> I should execute the query inside them, any way to easily read the value inside without make a lot of if statement
Anybody knows a good and easy way to achieve all this?
Thanks
There are a few ways to read the XML file and extract the information you need without using a lot of if statements. One approach is to use an XML parsing library such as JAXB or SAX, and create Java classes to represent the XML elements.
In JAXB, you can use the javax.xml.bind.Unmarshaller class to unmarshal the XML file into a Java object, which you can then traverse to extract the information you need.
You should start creating a Java classes based on the XML structure, like FlowMonitor, Menu1, Item, Connection etc. , and use annotation to map the xml elements to the fields.
Then, you can use the unmarshaller.unmarshal() method to parse the XML file and create an instance of the FlowMonitor class, which will contain all the information from the XML file.
Once you have the FlowMonitor object you can loop through the items, and get the description and filename by calling getDescriptionValue() and getFilenameValue() of the item object....
I am having some trouble using xpath to extract the "Payload" values below using apache-camel. I use the below xpath in my route for both of the example xml, the first example xml returns SomeElement and SomeOtherElement as expected, but the second xml seems unable to parse the xml at all.
xpath("//Payload/*")
This example xml parses just fine.
<Message>
<Payload>
<SomeElement />
<SomeOtherElement />
</Payload>
</Message>
This example xml does not parse.
<Message xmlns="http://www.fake.com/Message/1">
<Payload>
<SomeElement />
<SomeOtherElement />
</Payload>
</Message>
I found a similar question about xml and xpath, but it deals with C# and is not a camel solution.
Any idea how to solve this using apache-camel?
Your 2nd example xml, specifies a default namespace: xmlns="http://www.fake.com/Message/1" and so your xpath expression will not match, as it specifies no namespace.
See http://camel.apache.org/xpath.html#XPath-Namespaces on how to specify a namespace.
You would need something like
Namespaces ns = new Namespaces("fk", "http://www.fake.com/Message/1");
xpath("//fk:Payload/*", ns)
I'm not familiar with Apache-Camel, this was just a result of some quick googling.
An alternative maybe to just change your xPath to something like
xpath("//*[local-name()='Payload']/*)
Good luck.
i have this XML document:
<?xml version="1.0" encoding="UTF-16"?>
<root>
<items>
<item1>
<tag1>1</tag1>
<tag2>2</tag2>
<tag3>3</tag3>
</item1>
<item2>
<tag1>4</tag1>
<tag2>5</tag2>
<tag3>6</tag3>
</item2>
</items>
</root>
I want to iterate the item elements (item1, item2...), and for each tag get the tag name and after that the value of the tag.
I am using DOM parser.
Any ideas?
Sorry, but this ain't an unsolvable or complicated problem, this is simply reading a tutorial which can be googled within seconds.
And of course, you might also check the documentation, which will give you a hint about this handy method called "getNodeName()".
I want to parse like this xml file in java.
I know using SAX or DOM, we can parse XML file.
But as per my knowledge if xml is like this
<XML><FORM><ITEM>Name</ITEM> <ITEM>Area</ITEM> <ITEM>ZipCode</ITEM> </FORM></XML>
we can parse it.
How can i get other properties like label, title,type. as in this XML file.
How to do that?
Please help me!!!
<XML><FORM TITLE="Search" View="1"><ITEM Label="Name" Type="Alpha" maxWidth="25"ID="name" Align="LEFT"></ITEM> <ITEM Label="Area " Type="AlphaNumeric" maxWidth="20" ID="area" Align="LEFT"></ITEM> <ITEM Label="Zip Code" Type="Numeric" maxWidth="10" ID="zip" Align="LEFT"></ITEM><ITEM Label="Search within radius of" Type="Radio" maxWidth="20" ID="ID" Align=" CENTER"><LIST_VALUES><ID="20" VALUE="20 kms"<ID="50" VALUE="50 kms"> <ID="100" VALUE="20 kms"></LIST_VALUES></ITEM></FORM><XML>
TITLE, Label, etc are ATTRIBUTES of the various XML Nodes. Depending on the exact api you're using you'd generally find a method named something like getAttribute(String name) which would allow you to retrieve the content of the particular attribute.
I remember JDOM allowing you to call getAttribute(..) on an instance of an Element, which mapped to an XML node
Here is an exemple using DOM, once you have your ITEM element (for instance):
String labelValue= itemElement.getAttribute("Label");
I have a 'complex item' that is in XML, Then a 'workitem' (in xml) that contains lots of other info, and i would like this to contain a string that contains the complex item in xml.
for example:
<inouts name="ClaimType" type="complex" value="<xml string here>"/>
However, trying SAX and other java parsers I cannot get it to process this line, it doesn't like the < or the "'s in the string, I have tried escaping, and converting the " to '.
Is there anyway around this at all?? Or will I have to come up with another solution?
Thanks
I think you'll find that the XML you're dealing with won't parse with a lot of parsers since it's invalid. If you have control over the XML, you'll at a bare minimum need to escape the attribute so it's something like:
<inouts name="ClaimType" type="complex" value="<xml string here>" />
Then, once you've extracted the attribute you can possibly re-parse it to treat it as XML.
Alternatively, you can take one of the approaches above (using CDATA sections) with some re-factoring of your XML.
If you don't have control over your XML, you could try using the TagSoup library to parse it to see how you go. (Disclaimer: I've only used TagSoup for HTML, I have no idea how it'd go with non-HTML content)
(The tag soup site actually appears down ATM, but you should be able to find enough doco on the web, and downloads via the maven repository)
Possibly the easiest solution would be to use a CDATA section. You could convert your example to look like this:
<inouts name="ClaimType" type="complex">
<![CDATA[
<xml string here>
]]>
</inouts>
If you have more than one attribute you want to store complex strings for, you could use multiple child elements with different names:
<inouts name="ClaimType" type="complex">
<value1>
<![CDATA[
<xml string here>
]]>
</value1>
<value2>
<![CDATA[
<xml string here>
]]>
</value2>
</inouts>
Or multiple value elements with an identifying id:
<inouts name="ClaimType" type="complex">
<value id="complexString1">
<![CDATA[
<xml string here>
]]>
</value>
<value id="complexString2">
<![CDATA[
<xml string here>
]]>
</value>
</inouts>
CDATA section or escaping
NB There is a big difference between escaping and encoding, which some other posters have referred to. Be careful of confusing the two.
I'm not sure how it works for attributes, and if escaping (< as < and > as >) does not work, then I don't know.
If it were an inner tag: you could use the Xml Any mechanism (never used it myself) or declare it in a CDATA section.
you are http://www.doingitwrong.com/
If inouts/#value really is tree-structured (i.e. XML) then it shouldn't be an attribute, it should be a child element:
<inout name="ClaimType" type="complex">
<value>
<some-arbitrary>
<xml-stuff/>
</some-arbitrary>
</value>
</inout>
If it is not, in fact, guaranteed to be well-formed XML, but just sort of looks like it because you put some pointy brackets in it, then you should ask yourself if there isn't some better way to solve this problem. That failing, use <![CDATA[ as some have already suggested.