XML Parse - Issue with parsing text from specific Node [duplicate] - java

This question already has answers here:
Getting an attribute value in xml element
(3 answers)
Closed 5 years ago.
Face an issue in parsing XML to extract data from a specific node. I referred to Link1 Link2 Link3. Please note, am able to parse & get the data for other nodes in the below xml file like id, order_id etc. But for the below line / node, unable to extract the info of segment_id & instrument_id:
<trade segment_id="NSE-F&O " instrument_id="NSE:INFRATEL17NOVFUT">
Not sure if the way the XML file is setup or the way I am trying to extract the data for that specific node is wrong. Hope the specific issue I face is clear.
XML File:
<contract_note version="0.1">
<contracts>
<contract>
<id>CNT-17/18-5310750</id>
<name>CONTRACT NOTE CUM BILL</name>
<description>None</description>
<timestamp>2017-11-01</timestamp>
<trades>
<trade segment_id="NSE-F&O " instrument_id="NSE:INFRATEL17NOVFUT">
<id>37513030</id>
<order_id>1300000000352370</order_id>
<timestamp>09:20:48</timestamp>
<description>None</description>
<type>buy</type>
<quantity>1700</quantity>
<average_price>444.2</average_price>
<value>755140.0</value>
</trade>
</trades>
</contract>
</contracts>
</contract_note>
Code:
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
NodeList cNoteList = doc.getElementsByTagName("contract");
Node nNode = cNoteList.item(0);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
for (int j = 1; j <= eElement.getElementsByTagName("trade").getLength(); j++) {
// Check if data can be read for Node - 'id'
System.out.println(eElement.getElementsByTagName("id").item(j).getTextContent();
// Check if data can be read for segment_id & instrument_id
System.out.println("Scrip: " + eElement.getElementsByTagName("trade").item(0).getTextContent());
}
}catch (Exception e) {
e.printStackTrace();
}
Edit:
Corrected the xml file info provided above.

As #Juan commented, your XML is bad. Fix it by following the required XML escaping rules and replacing segment_id="NSE-F&O " with segment_id="NSE-F&O ".
If you cannot change the XML, then see How to parse invalid (bad / not well-formed) XML? for options, but the best option is to fix the XML at the source.

Related

Using XPath count function

I am using a oracle sql database to carryout sql queries with xpath expressions – I have created an XML file which contains data relating to a film
The XPath expression you're looking for (not the SQL expression) is:
count(/film/directors/director)
which result should be 1 with your example XML file.
If you want to check if it's 2, use
count(/film/directors/director) = 2
which should return FALSE with your XML file.
First, you obviously know you need to use xPath to query the XML file, but you seem to have failed to understand what xPath is or how it should be used.
My first suggestion would be to go a read up on xPath and xPath in Java because it has nothing to do with the SQL.
I then did a quick search on "java xpath count" and come across a number of excellent examples, but based on XPath count() function, I went about testing your document with...
try {
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
DocumentBuilder b = f.newDocumentBuilder();
// This is your document in a file
Document d = b.parse(new File("Test.xml"));
d.getDocumentElement().normalize();
String expression = "//film[count(directors)=1]";
XPath xPath = XPathFactory.newInstance().newXPath();
Object result = xPath.compile(expression).evaluate(d, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
System.out.println(nodes.getLength());
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
System.out.println("Found " + node.getTextContent());
}
} catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException | DOMException exp) {
exp.printStackTrace();
}
This basically listed the film node (found one match) ... but, why did you produce a result?! Look at the query, //film[count(directors)=1], it's listing all film matches with a one director, because I want to test the query. Change it to //film[count(directors)=2] and it will return a result of zero matches based on your example.
I would highly recommend that you pause for a moment and become more familiar with what xPath is and how it works before you continue

XML node list as JavaFX observable list? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
got a problem...
I have some XML file with root element, 3 element with same name and different attribute and also each element has got some elements.
I want to have element attributes called "id" in FX observable list.
No idea what to do.
Since you didn´t give me much information, I have to explain it with some dummy-code.
So let´s say you have this XML:
<root id="0">
<sub1 id="1">
<hell1>hell1</hell1>
</sub1>
<sub2>
<hell2 id="2">hell2</hell2>
</sub2>
<sub3>sub3</sub3>
</root>
Please note, that the "id"-attributes are in different element levels, as you said.
From here I would also advise you to use xpath like Heri.
The simplest xpath to get all elements with "id"-attributes from XML is:
//*[#id]
If you don´t know how to work with XML and Xpath in Java you can look it up here:
How to read XML using XPath in Java
Which is the best library for XML parsing in java
If i wanted to get all "id"-attribute values from my XML it would look like this:
// My Test-XML
final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<root id=\"0\">\n" +
"\t<sub1 id=\"1\">\n" +
"\t\t<hell1>hell1</hell1>\n" +
"\t</sub1>\n" +
"\t<sub2>\n" +
"\t\t<hell2 id=\"2\">hell2</hell2>\n" +
"\t</sub2>\n" +
"\t<sub3>sub3</sub3>\n" +
"</root>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
// Here you have to put your XML-Source (String, InputStream, File)
Document doc = builder.parse(new InputSource(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))));
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
// The xpath from above
XPathExpression expr = xpath.compile("//*[#id]");
// Here you get the node-list of all elements with an attribute named "id"
NodeList nodeList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
// run through all nodes
Node node = nodeList.item(i);
// fetch the values from the "id"-attribute
final String idValue = node.getAttributes().getNamedItem("id").getNodeValue();
// Do something awesome!!!
System.out.println(idValue);
}
I assume that you know how to put the values into your observable list then. :)
If you have any more questions, feel free to ask.
PS: If you show me your XML, I can help you in a more efficient way.

Parsing XML file Using Java (DOM parser)

Ok, so I have been able to kind of parse through this xml file. But I am unable to get to the section I want.
http://www.faroo.com/api?q=iphone&start=1&length=10&l=en&src=news&f=rss
This is the URL to the xml because it looks very ugly just pasted on here. I have gone through this xml and have copied it to a file. The part that I need is the "title" in the first "item". I have gone through with this code:
System.out.println(myDocument.getElementsByTagName("item").item(0).getTextContent());
And this just prints all of the contents of the first "item", like "title" and "link" and "description" but I do not want all of it, I only want "title" to be printed. I have having problems getting it to work exactly right, but I feel like I am close. Any help will be appreciated. Thanks.
From the Oracle documentation on the org.w3c.dom package:
This attribute returns the text content of this node and its descendants.
Your code is calling getTextContent() on the item tag. If you modify your code so that it retrieves the text from the title tag, it works correctly.
System.out.println(myDocument.getElementsByTagName("item").item(0).getFirstChild().getTextContent());
Note that this relies on title being the first child tag in item. You may want to change this to a more order-independant solution.
Below is a code that iterates through the whole rss and gets all the titles, links and descriptions. You can create an object that has title, link and description as attributes and use it as you please:
try {
File fXmlFile = new File("api.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("item");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
System.out.println("title : " + eElement.getElementsByTagName("title").item(0).getTextContent());
System.out.println("link : " + eElement.getElementsByTagName("link").item(0).getTextContent());
System.out.println("description : " + eElement.getElementsByTagName("description").item(0).getTextContent());
}
}
} catch (Exception e) {
e.printStackTrace();
}
Hope that helps.

Reading XML in java using DOM

I am new to read XML in Java using DOM. Could someone help me with simple code steps to read this XML in DOM?
Here is my XML:
<DataSet xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='datamartschema.1.3.xsd'>
<DataStream title='QUESTIONNAIRE'>
<Record>
<TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>xhaksdj</SubType>
<IntegerValue title='ComponentID'>11111</IntegerValue>
</Record><Record>
<TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>jhgjhg</SubType>
<IntegerValue title='ComponentID'>11111</IntegerValue>
</Record>
</DataStream>
</DataSet>
In this XML I need to read the DataStream value and Record values. My expected output is
DataStream=QUESTIONNAIRE and my records are
<TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>xhaksdj</SubType><IntegerValue title='ComponentID'>11111</IntegerValue><TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>jhgjhg</SubType><IntegerValue title='ComponentID'>11111</IntegerValue>
How can I get this output? I tried myself but I can't get the records output like above. I get the output without Tags which are present in the above output.I am using this line to get the output. But it does not give me correct output. Also, how to read the datastream value from this XML? Kindly help me.
This is my code snippets
NodeList datasetallRecords = indElement.getElementsByTagName("Record");
for (int y = 0; y < datasetallRecords.getLength(); y++) {
Element recordsElement = (Element) datasetallRecords.item(y);
recordXMl = recordXMl + recordsElement.getTextContent();
String d = datasetallRecords.item(y).getTextContent();
if (recordsElement.getTagName().equalsIgnoreCase("SubType")) {
lsDataStreamSubTypes.add(recordsElement.getTextContent());
}
recordCount = y;
}
When you create new instance of builder you can get DataStream
it would be look like this:
Element root = document.getDocumentElement();
NodeList dataStreams = root.getElementsByTagName("DataStream");
then get throw this list and get all info like this:
for (int i = 0; i < dataStreams.lenght(); i++) {
Element dataStream = (Element) dataStreams.item(i);
if (dataStream.getNodeType() == Element.ELEMENT_NODE) {
String title = dataStream.getAttributes()
.getNamedItem("title").getTextContent();
}
}
First you need to create a Node like this
Node nNode = datasetallRecords.item(y);
then an element like this
Element eElement = (Element) nNode;
now you can start taking the values from the element by using the getelementbyid and getnodevalue method.
You're not getting the tags because the call to getTextContent() on the "Record" node will return only the textual content of that node and its descendants.
If you need to nodes as well you'll have to process the XML by hand. Have a look at the DOM tutorial it covers processing a document in DOM mode very well including how to read out element names.

How do I get the tag 'Name' from a XML Node in Java (Android)

I have a tiny little problem parsing an XML file in Java (Android).
I have an XML file that is like this:
<Events>
<Event Name="Olympus Has Fallen">
...
</Event>
<Event Name="Iron Man 3">
...
</Event>
</Events>
I already managed to get the NodeList by doing this:
URL url = new URL("********");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(url.openStream()));
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("Event");
Also I managed to get every single item of the NodeList by doing this:
for (int i = 0; i < nodeList.getLength(); i++) {
// Item
Node node = nodeList.item(i);
Log.i("film", node.getNodeName());
}
But this just Logs: "Event" instead of the value of the Name tag.
How do I output the value of this 'name' tag from the XML.
Can anyone help me with this one?
Thanks in advance!
But this just Logs: "Event" instead of the value of the Name tag.
Yes, because you're asking for the name of the element. There isn't a Name "tag" - there's a Name attribute, and that's what you should find:
// Only check in elements, and only those which actually have attributes.
if (node.hasAttributes()) {
NamedNodeMap attributes = node.getAttributes();
Node nameAttribute = attributes.getNamedItem("Name");
if (nameAttribute != null) {
System.out.println("Name attribute: " + nameAttribute.getTextContent());
}
}
(It's very important to be precise in terminology - it's worth knowing the difference between nodes, elements, attributes etc. It will help you enormously both when communicating with others and when looking for the right bits of API to call.)

Categories