Get xml value by element name - java

How can i get XML value by attribute for the below XML:
I have tried:
String xml = "<Info><document><document>234doc</document></document></Info>";
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new InputSource(new StringReader(xml)));
NodeList errNodes = doc.getElementsByTagName("error");
if (errNodes.getLength() > 0) {
Element err = (Element)errNodes.item(0);
} else {
Node value = doc.getElementsByTagName("document").item(0);
out.println(value);
}
I am looking for the output: "234doc". But I am not sure how do get the value. Can any one please suggest?

This is not a rocket science. You should debug your code, explore classes you might already know (Document, NodeList, Node, Element) and understand your xml structure (for more info look here). One way to achieve your result is:
System.out.println(doc.getChildNodes().item(0).getTextContent());

Related

Read Complex Xml file in java

I am able to read many type of xml file in java. but today i got a xml file and not able to read its details.
<ENVELOPE>
<BILLFIXED>
<BILLDATE>1-Jul-2017</BILLDATE>
<BILLREF>1</BILLREF>
<BILLPARTY>Party1</BILLPARTY>
</BILLFIXED>
<BILLCL>-10800.00</BILLCL>
<BILLPDC/>
<BILLFINAL>-10800.00</BILLFINAL>
<BILLDUE>1-Jul-2017</BILLDUE>
<BILLOVERDUE>30</BILLOVERDUE>
<BILLFIXED>
<BILLDATE>1-Jul-2017</BILLDATE>
<BILLREF>2</BILLREF>
<BILLPARTY>Party2</BILLPARTY>
</BILLFIXED>
<BILLCL>-2000.00</BILLCL>
<BILLPDC/>
<BILLFINAL>-2000.00</BILLFINAL>
<BILLDUE>1-Jul-2017</BILLDUE>
<BILLOVERDUE>30</BILLOVERDUE>
<BILLFIXED>
<BILLDATE>1-Jul-2017</BILLDATE>
<BILLREF>3</BILLREF>
<BILLPARTY>Party3</BILLPARTY>
</BILLFIXED>
<BILLCL>-1416.00</BILLCL>
<BILLPDC/>
<BILLFINAL>-1416.00</BILLFINAL>
<BILLDUE>31-Jul-2017</BILLDUE>
<BILLOVERDUE>0</BILLOVERDUE>
</ENVELOPE>
I am using this code for read xml file. I am able to read data inside <BILLFIXED> tag but not able to read data outside of this like <BILLFINAL> and <BILLDUE> etc.
try {
File fXmlFile = new File("filepath");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList billNodeList = doc.getElementsByTagName("ENVELOPE");
for(int i=0;i<billNodeList.getLength();i++){
Node voucherNode = billNodeList.item(i);
Element voucherElement = (Element) voucherNode;
NodeList nList = voucherElement.getElementsByTagName("BILLFIXED");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node insideNode = nList.item(temp);
Element voucherElements = (Element) insideNode;
System.out.println(voucherElements.getElementsByTagName("BILLDATE").item(0).getTextContent());
System.out.println(voucherElements.getElementsByTagName("BILLREF").item(0).getTextContent());
System.out.println(voucherElements.getElementsByTagName("BILLPARTY").item(0).getTextContent());
System.out.println(voucherElements.getElementsByTagName("BILLFINAL").item(0).getTextContent());
System.out.println(voucherElements.getElementsByTagName("BILLOVERDUE").item(0).getTextContent());
}
}
} catch (Exception e) {
e.printStackTrace();
}
I am try all possible way which i know that but currently i am not able to find any solution.
If anyone have any solution please share with me.
One way to do it, is to "fix" the XML to be more well-structured, e.g. like this:
// Fix the XML
Element envelopeElem = doc.getDocumentElement();
List<Node> children = new ArrayList<>();
for (Node child = envelopeElem.getFirstChild(); child != null; child = child.getNextSibling())
children.add(child);
Element billElem = null;
for (Node child : children) {
if (child.getNodeType() == Node.ELEMENT_NODE && "BILLFIXED".equals(child.getNodeName()))
envelopeElem.insertBefore(billElem = doc.createElement("BILL"), child);
if (billElem != null)
billElem.appendChild(child);
}
The code basically creates a new <BILL> element as a child of <ENVELOPE> whenever it encounters a <BILLFIXED> element, then moves all subsequent nodes into the <BILL> element.
The result is that the XML in the DOM tree looks like this1, which should be easier for you to process:
<ENVELOPE>
<BILL>
<BILLFIXED>
<BILLDATE>1-Jul-2017</BILLDATE>
<BILLREF>1</BILLREF>
<BILLPARTY>Party1</BILLPARTY>
</BILLFIXED>
<BILLCL>-10800.00</BILLCL>
<BILLPDC/>
<BILLFINAL>-10800.00</BILLFINAL>
<BILLDUE>1-Jul-2017</BILLDUE>
<BILLOVERDUE>30</BILLOVERDUE>
</BILL>
<BILL>
<BILLFIXED>
<BILLDATE>1-Jul-2017</BILLDATE>
<BILLREF>2</BILLREF>
<BILLPARTY>Party2</BILLPARTY>
</BILLFIXED>
<BILLCL>-2000.00</BILLCL>
<BILLPDC/>
<BILLFINAL>-2000.00</BILLFINAL>
<BILLDUE>1-Jul-2017</BILLDUE>
<BILLOVERDUE>30</BILLOVERDUE>
</BILL>
<BILL>
<BILLFIXED>
<BILLDATE>1-Jul-2017</BILLDATE>
<BILLREF>3</BILLREF>
<BILLPARTY>Party3</BILLPARTY>
</BILLFIXED>
<BILLCL>-1416.00</BILLCL>
<BILLPDC/>
<BILLFINAL>-1416.00</BILLFINAL>
<BILLDUE>31-Jul-2017</BILLDUE>
<BILLOVERDUE>0</BILLOVERDUE>
</BILL>
</ENVELOPE>
1) The XML has been reformatted for human readability, i.e. it has been re-indented.
It isn't well-structured XML. Inside your <envelope> tags there is nothing to indicate the start of each set of six attributes that constitute a 'bill'. You'd normally expect that each one would have a <bill> and </bill> tag to contain them. And this is going to confuse the parser...
As per sample XML, it has data for 3 records. But each record does not have any separation. Looks like each field data populated into XML tag and written into file.
There 2 possible option I would suggest
JAVA based : As Andreas suggested, Read the file content and add a root tag for each record which would give finite XML structure then would be easier to handle. Performance impact may raise when the input file is in large size.
Transformation based : Try STX transformation which would convert the structure to required format either XML or even flat file. Then processing would be simpler

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.)

Inserting a node in an xml file

I would like to insert a node in an xml file using Java DOM. I am actually editing a lot of contents of a dummy file in order to mofidy it like the original.
I would want to add an open node and close node in between the following file;
<?xml version="1.0" encoding="utf-8"?>
<Memory xmlns:xyz="http://www.w3.org/2001/XMLSchema-instance"
xmlns:abc="http://www.w3.org/2001/XMLSchema" Derivative="ABC"
xmlns="http://..">
///////////<Address> ///////////(which I would like to insert)
<Block ---------
--------
-------
/>
////////// </Address> /////////(which I would like to insert)
<Parameters Thread ="yyyy" />
</Memory>
I hereby request you to let me know how to I insert -- in between the xml file?
Thanks in advance.!
What I have tried doing is;
Element child = doc.createElement("Address");
child.appendChild(doc.createTextNode("Block"));
root.appendChild(child);
But this gives me an output like;
<Address> Block </Address> and not the way i expect :(
And now, what I have tried is to add these lines;
Element cd = doc.createElement("Address");
Node Block = root.getFirstChild().getNextSibling();
cd.appendChild(Block);
root.insertBefore(cd, root.getFirstChild());
But still, this is not the output which i am looking for. I got this output as
---------
What you want is probably:
Node parent = block.getParentNode()
Node blockRemoved = parent.removeChild(block);
// Create address
parent.appendChild(address);
address.appendChild(blockRemoved);
This is the standard way to re-attach a node in another place under W3C DOM.
Here:
DocumentBuilder b = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = b.parse(...);
// Parent of existing Block elements and new Address elemet
// Might be retrieved differently depending on
// actual structure
Element parent = document.getDocumentElement();
Element address = document.createElement("address");
NodeList nl = parent.getElementsByTagName("Block");
for (int i = 0; i < nl.getLength(); ++i) {
Element block = (Element) nl.item(i);
if (i == 0)
parent.insertBefore(address, block);
parent.removeChild(block);
address.appendChild(block);
}
// UPDATE: how to pretty print
LSSerializer serializer =
((DOMImplementationLS)document.getImplementation()).createLSSerializer();
serializer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
LSOutput output =
((DOMImplementationLS)document.getImplementation()).createLSOutput();
output.setByteStream(System.out);
serializer.write(document, output);
I assume you are using the W3C DOM (e.g. http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html ). If so try
insertBefore(address, block);

How to read an attribute tag with an equals sign from XML in Java?

I'm parsing an XML file through Java, and am able to parse through Nodes in the XML file that appear as:
<name><given>familyName</given></name>
by using code such as the snippet shown below:
NodeList givenElmntLst = firstElement.getElementsByTagName("given");
Element givenNmElmnt = (Element) givenElmntLst.item(0);
NodeList fstNm = givenNmElmnt.getChildNodes();
String given = ((Node) fstNm.item(0)).getNodeValue();
but I am unable to read attributes that are formatted as such:
<birthTime value="19230101"/>
How should I be reading values such as the one above differently? Thanks in advance.
i'm assuming your using the org.w3c.dom package...
try something like this:
NodeList birthTimeLst = firstElement.getElementsByTagName("birthTime");
Element birthTime = (Element) birthTimeLst.item(0);
String value = birthTime.getAttribute("value");

Categories