How to get containing Node Name from xml namespace - java

I've got XPath of XML with it's structure like
<Statement xsi:type="conditionStatement">
<Id>CONDITION_0001</Id>
<Bounds>
<xValue>13</xValue>
<yValue>145</yValue>
<Height>402</Height>
<Width>513</Width>
</Bounds>
.........
.........
</statement>
Xpath takes me to xsi:type. But when I'm trying to get the name of node which is "statement" as expected, it's getting null.
My code for this is:-
nodeList = (NodeList) xPath.compile(xPathSrcFile).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
nodeList.item(i).getParentNode();
}
For rest of the cases, code is working perfectly fine but when it gets to "xsi", code is throwing nullpointer exception.
Need some help to get node name from this.

try this
NodeList nodeList = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputStream inputStream= new FileInputStream(file);//xmlDocument as file
Reader reader = new InputStreamReader(inputStream,"ISO-8859-1");
InputSource is = new InputSource(reader);
is.setEncoding("ISO-8859-1");
Document doc = db.parse(is);
Element docEle = doc.getDocumentElement();
nodeList = docEle.getElementsByTagName("Statement");

1 Your XML file is incorrect:
it begins with Statement
and ends with /statement
2 you need this at root tag:
< root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
3 to get the name of you tag, use:
nodeList.item(i).getTagName();
4 what is your Xpath ?

Related

How to dynamically assign attribute values in Xpath

I am trying to find the NodeList of the nodes containing any number of certain attributes in the XML file.
I can do the following and get the NodeList
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document schDoc = db.newDocument();
InputStream schStream = new ByteArrayInputStream(sch.xml);
schDoc = db.parse(schStream)
schDoc.getDocumentElement().normalize();
XPath xpath1 = XPathFactory.newInstance().newXpath();
String expAttStr = "descendant-or-self::*[contains(#Name,'total_amt')]";
XPathExpression exprForTotalAmt = xpath1.compile(expAttStr);
NodeList totalAmtNodeList = (NodeList) exprForTotalAmt.evaluate(schDoc,XPathConstants.NODESET);
This is good.. But how can I loop and change the value of the attribute name. I tried the following and didn't work:
List<String> listOfItems= Arrays.asList("total_amt", "purchase_amt", "sales_amt");
long count = listOfItems.stream.distinct().count();
for(int i = 0; i<count; i++){
String expAttStr = "descendant-or-self::*[contains(#Name,listOfItems.get(i)]";
XPathExpression exprForTotalAmt = xpath1.compile(expAttStr);
NodeList totalAmtNodeList = (NodeList) exprForTotalAmt.evaluate(schDoc,XPathConstants.NODESET);
//some tasks
}
Would really appreciate it if anyone can point me in the right direction. Thanks.

Import Tag from xml file to another using JAVA

I do my work with this piece and my problem is simple. Just changing the place of transfer. I did not know what is the matter responsible for determining the place of transportation in the first or last content.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
Document doc = null;
Document doc2 = null;
String a = "E:\\1.xml" ;
String c ;
try {
db = dbf.newDocumentBuilder();
doc = db.parse(new File(a));
doc2 = db.parse(new File("E:\\L (1).xml"));
NodeList ndListFirstFile = doc.getElementsByTagName("med");
Node nodeArea = doc.importNode(doc2.getElementsByTagName("end").item(0), true);
NodeList nList2 = doc2.getElementsByTagName("end");
for (int i = f; i <g; i++) {
c = +i+"" ;
doc2 = db.parse(new File("E:\\L ("+c+").xml"));
for (int temp = 0; temp < nList2.getLength(); temp++) {
nodeArea = doc.importNode(doc2.getElementsByTagName("end").item(temp), true);
ndListFirstFile.item(0).appendChild(nodeArea);
}
}
This is done from two files, and it works well, but the place of transferring the tag is at the end of the content. I want it at the beginning of the content
<med>
I move the Tag "dat" and it is moved at the end of the Tag "med" content
<dat>We have come to the wrong place, my friend</dat></med>
<med><dat>We want to get better here</dat>
I want to move Tag dat
To be the first content from Tag med
</med>
That's it
From the appendChild docs:
Adds the node newChild to the end of the list of children of this node.
So it is adding it to the end as expected.
To insert it before any other element on that node, you can try:
ndListFirstFile.item(0).insertBefore(nodeArea, ndListFirstFile.item(0).getFirstChild());

use xpath to extract value from xml file with multiple namespace in java

I am trying to extract node value with multiple namespaces in java but not succeed. The xml file is like:
<ns26:start xmlns:ns26="http://www.tektronix.com/iris/isa/capture/start"
xmlns:ns31="http://www.tektronix.com/iris/isa/filters"
xmlns:ns13="http://www.tektronix.com/iris/isa/monitoredObjects"
xmlns:ns6="http://www.tektronix.com/iris/isa"
xmlns:ns10="http://www.tektronix.com/iris/isa/monNodeObjects"
xmlns:ns7="http://www.tektronix.com/iris/isa/capture/monitoredElements"
xmlns:ns11="http://www.tektronix.com/iris/isa/pointcodes"
xmlns:ns8="http://www.tektronix.com/iris/isa/capture/captureSession"
xmlns:ns2="http://www.tektronix.com/iris/isa/sessionSaveInfo"
xmlns:ns4="http://www.tektronix.com/iris/isa/customData"
xmlns:ns3="http://www.tektronix.com/iris/isa/manifest">
<ns6:Id>LAB:11300/isaclient;440</ns6:Id>
</ns26:start>
I want to extract Id with xpath local-name(). Expression like //*[local-name()='start']/*[local-name()='Id'] but didn't get any matched node. Please help to find issue here. Thanks
Add the java code here:
public static List<String> getXPathValueNamespace(String xml, String expression throws ParserConfigurationException, SAXException, IOException, XPathExpressionException
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder;
Document doc = null;
List<String> list = new ArrayList<String>();
builder = factory.newDocumentBuilder();
InputSource source = new InputSource(new StringReader(xml));
doc = builder.parse(source);
// Create XPathFactory object
XPathFactory xpathFactory = XPathFactory.newInstance();
// Create XPath object
XPath xpath = xpathFactory.newXPath();
XPathExpression expr = xpath.compile(expression);
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++)
list.add(nodes.item(i).getNodeValue());
return list;
}
The expression //*[local-name()='start']/*[local-name()='Id'] works and for the example document one node should be contained in the result node list.
But you should use nodes.item(i).getTextContent() to retrieve the node content, since getNodeValue() returns null for element nodes.

How to extract XML data using Java in Android?

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

Retrieve values from XML tag in Java

I have a set of XML string outputs from a natural language tool and need to retrieve values out of them, also provide null value to those tags that are not presented in the output string. Tried to use the Java codes provided in Extracting data from XML using Java but it doesn't seem to work.
Current sample tag inventory is listed below:
<TimeStamp>, <Role>, <SpeakerId>, <Person>, <Location>, <Organization>
Sample XML output string:
<TimeStamp>00.00.00</TimeStamp> <Role>Speaker1</Role><SpeakerId>1234</SpeakerId>Blah, blah, blah.
Desire outputs:
TimeStamp: 00.00.00
Role: Speaker1
SpeakerId: 1234
Person: null
Place: null
Organization: null
In order to use the Java codes provided in above link (in updated code), I inserted <Dummy> and </Dummy> as follows:
<Dummy><TimeStamp>00.00.00</TimeStamp><Role>Speaker1</Role><SpeakerId>1234</SpeakerId>Blah, blah, blah.</Dummy>
However, it returns dummy and null only. Since I'm still a newbie to Java, detailed explanations will be much appreciated.
Try this way :D hope can help you
File fXmlFile = new File("yourfile.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
You can get child node list like this:
NodeList nList = doc.getElementsByTagName("staff");
Get the item like this:
Node nNode = nList.item(temp);
Example Site
This is what I ended up doing for my Java wrapper (Show TimeStamp only)
public class NERPost {
public String convertXML (String input) {
String nerOutput = input;
try {
DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(nerOutput));
Document doc = docBuilder.parse(is);
// normalize text representation
doc.getDocumentElement ().normalize ();
NodeList listOfDummies = doc.getElementsByTagName("dummy");
for(int s=0; s<listOfDummies.getLength() ; s++){
Node firstDummyNode = listOfDummies.item(s);
if(firstDummyNode.getNodeType() == Node.ELEMENT_NODE){
Element firstDummyElement = (Element)firstDummyNode;
//Convert each entity label --------------------------------
//TimeStamp
String ts = "<TimeStamp>";
Boolean foundTs;
if (foundTs = nerOutput.contains(ts)) {
NodeList timeStampList = firstDummyElement.getElementsByTagName("TimeStamp");
//do it recursively
for (int i=0; i<timeStampList.getLength(); i++) {
Node firstTimeStampNode = timeStampList.item(i);
Element timeStampElement = (Element)firstTimeStampNode;
NodeList textTSList = timeStampElement.getChildNodes();
String timeStampOutput = ((Node)textTSList.item(0)).getNodeValue().trim();
System.out.println ("<TimeStamp>" + timeStampOutput + "</TimeStamp>\n")
} //end for
}//end if
//other XML tags
//.....
}//end if
}//end for
}
catch...
}//end try
}}

Categories