How to insert compleate java NodeList into xml document? - java

I would like to add complete NodeList into xml document:
I get my NodeList from document1 as follow:
NodeList myNList=doc1.getElementsByTagName("APPLICATION");
This nodeList contains some nodes with many attributes and I would like to insert this nodeList into other document doc2 in node USER with the name "Nina"
doc2.xml:
<document>
<USER name="Nina">
// nodeList should be inserted here
</USER>
What is the best way do do this without having to create new elements/nodes in doc2?

Related

Extracting the node values in XML with XPath in Java

I have an XML document:
<response>
<result>
<phone>1233</phone>
<sys_id>asweyu4</sys_id>
<link>rft45fgd</link>
<!-- Many more in result -->
</result>
<!-- Many more result nodes -->
</response>
The XML structure is unknown. I am getting XPath for attributes from user.
e.g. inputs are strings like:
//response/result/sys_id , //response/result/phone
How can I get these node values for whole XML document by evaluating XPath?
I referred this but my xpath is as shown above i.e it does not have * or text() format.
The xpath evaluator works perfectly fine with my input format, so is there any way I can achieve the same in java?
Thank you!
It's difficult without seeing your code... I'd just evaluate as a NodeList and then call getTextContent() on each node in the result list...
String input = "<response><result><phone>1233</phone><sys_id>asweyu4</sys_id><link>rft45fgd</link></result><result><phone>1233</phone><sys_id>another-sysid</sys_id><link>another-link</link></result></response>";
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new ByteArrayInputStream(input.getBytes("UTF-8")));
XPath path = XPathFactory.newInstance().newXPath();
NodeList node = (NodeList) path.compile("//response/result/sys_id").evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < node.getLength(); i++) {
System.out.println(node.item(i).getTextContent());
}
Output
asweyu4
another-sysid

Using Document Nodes in Java

I'm trying to read an xml file, for example: http://www1.skysports.com/feeds/11095/news.xml
I need to be able to getTextContent() for all the titles, descriptions etc that are children of <item> tags. There is a <title> tag that is not a child of an <item> tag that i dont want to getTextContent() for.
I've set up my XML reader so that i have:
Document doc = dbuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
String Title = document.getElementsByTagName("title").item(0).getTextContent();
but this method picks up the <title> that isnt a child of <item>
I could just change the item(0) to item(1) but I need this algorithm to work with various XML files that wont necessarily have the initial <title> without the <item> parent.
how can I just select those <title>s that are children of <item>s?
Use XPath instead. Makes it all a lot easier:
XPathFactory xpf = XPathFactory.newInstance();
XPath xp = xpf.newXPath();
NodeList nl = (NodeList) xp.evaluate("//item/title/text()", doc,
XPathConstants.NODESET);
for (int i = 0; i < nl.getLength(); ++i) {
System.out.println(nl.item(i).getNodeValue());
}

Issues with xpath context

I have a simple xml document:
<Results>
<Result>
<Number>1</Number>
<Data>a</Data>
</Result>
<Result>
<Number>2</Number>
<Data>b</Data>
</Result>
</Results>
I'm trying to get the data and number of each result using this code:
XPathExpression resExpr = xpath
.compile("//Results/Result");
XPathExpression numExpr=xpath
.compile("//Result/Number");
XPathExpression dataExpr=xpath
.compile("//Result/Data");
NodeList nodeList = (NodeList) resExpr.evaluate(root_node,
XPathConstants.NODESET);
for (int i=0;i<nodeList.getLength();i++) {
Node result=nodeList.item(i);
if (result!=null) {
Node numNode=(Node) numExpr.evaluate(result,
XPathConstants.NODE);
Node dataNode=(Node) dataExpr.evaluate(result,
XPathConstants.NODE);
String data=dataNode.getTextContent());
String num=numNode.getTextContent());
}
}
However, I get 1/a on both iterations. It seem that passing a node doesn't make xpath use it as context, but rather it's looking at whole tree?
This is because your xpath expression start with //. This means start searching from document root any child.
To access child of current node try .// for child in any deep, or ./ for direct child.
Or, because the current not in iteration is Result you can use:
XPathExpression numExpr=xpath
.compile("Number");
XPathExpression dataExpr=xpath
.compile("Data");

Java XPath: Get all the elements that match a query

I want to make an XPath query on this XML file (excerpt shown):
<?xml version="1.0" encoding="UTF-8"?>
<!-- MetaDataAPI generated on: Friday, May 25, 2007 3:26:31 PM CEST -->
<Component xmlns="http://xml.sap.com/2002/10/metamodel/webdynpro" xmlns:IDX="urn:sap.com:WebDynpro.Component:2.0" mmRelease="6.30" mmVersion="2.0" mmTimestamp="1180099591892" name="MassimaleContr" package="com.bi.massimalecontr" masterLanguage="it">
...
<Component.UsedModels>
<Core.Reference package="com.test.test" name="MasterModel" type="Model"/>
<Core.Reference package="com.test.massimalecontr" name="MassimaleModel" type="Model"/>
<Core.Reference package="com.test.test" name="TravelModel" type="Model"/>
</Component.UsedModels>
...
I'm using this snippet of code:
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document document = builder.parse(new File("E:\\Test branch\\test.wdcomponent"));
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
xpath.setNamespaceContext(new NamespaceContext() {
...(omitted)
System.out.println(xpath.evaluate(
"//d:Component/d:Component.UsedModels/d:Core.Reference/#name",
document));
What I'm expecting to get:
MasterModel
MassimaleModel
TravelModel
What I'm getting:
MasterModel
It seems that only the first element is returned. How can I get all the occurrences that matches my query?
You'll get a item of type NodeList
XPathExpression expr = xpath.compile("//Core.Reference");
NodeList list= (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
System.out.println(node.getTextContent());
// work with node
See How to read XML using XPath in Java
As per that example, If you first compile the XPath expression then execute it, specifying that you want a NodeSet back you should get the result you want.

How to parse this XML file

I am new to programming in java and i have just learned how to parse an xml file. But i am not getting any idea on how to parse this xml file. Please help me with a code on how to get the tags day1 and their inner tags order1,order2
<RoutePlan>
<day1>
<Order1>
<customer> XYZ</customer>
<address> INDIA </address>
<data> 10-10-2011 </data>
<time> 9.30 A.M </time>
</Order1>
<Order2>
<customer> ABC </customer>
<address> US </address>
<data> 10-10-2011 </data>
<time> 10.30 A.M </time>
</Order2>
</day1>
I wrote the following code to retrieve. But i am only getting the data in order1 but not in order2
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(file);
document.getDocumentElement().normalize();
System.out.println("Root Element: "+document.getDocumentElement().getNodeName());
NodeList node = document.getElementsByTagName("day1");
for(int i=0;i<node.getLength();i++){
Node firstNode = node.item(i);
Element element = (Element) firstNode;
NodeList customer = element.getElementsByTagName("customer");
Element customerElement = (Element) customer.item(0);
NodeList firstName = customerElement.getChildNodes();
System.out.println("Name: "+((firstName.item(0).getNodeValue())));
NodeList address = element.getElementsByTagName("address");
Element customerAddress = (Element) address.item(0);
NodeList addName = customerAddress.getChildNodes();
System.out.println("Address: "+((addName.item(0).getNodeValue())));
NodeList date = element.getElementsByTagName("date");
Element customerdate = (Element) date.item(0);
NodeList dateN = customerdate.getChildNodes();
System.out.println("Address: "+((dateN.item(0).getNodeValue())));
NodeList time = element.getElementsByTagName("time");
Element customertime = (Element) time.item(0);
NodeList Ntime = customertime.getChildNodes();
System.out.println("Time: "+((Ntime.item(0).getNodeValue())));
}
I can give you not one, not two, but three directions to parse this XML (there are more but let's say they are the most commons ones):
DOM -> two good resources to start : here and here
SAX -> quickstart from official website: here
StAX -> a good introduction: here
Judging by the size of your XML document, I'd probably go for a DOM parsing, which gonna be the easiest to implement and to use (but if you have to deal with larger files, take a look at SAX for reading-only manipulations and StAX for reading and writing ones).
The reason you are getting only "Order1" elements is because:
You lock on the "day1" node.
You retrieve the "customer" elements by tag name which returns 2 elements.
You retrieve the first element and print its value and hence the second "customer" is ignored.
When working with DOM, be prepared to spin up multiple loops for retrieving data. Also, you are a bit misguided when it comes to representing your schema. You really don't need to name "elements" as "day1"/"order1" etc. In XML, that can be simply expressed by having multiple "day" or "order" elements which in turn automatically enforces ordering. An example XML would look like:
<route-plan>
<day>
<order>
<something>
</order>
</day>
<day>
<order>
<something>
</order>
</day>
</route-plan>
Now retrieving "day" elements is a simple matter of:
Look up "day" elements by tag name
For each "day" element
Look up "order" element by tag name
For each "order" element
Print out the value of "customer"/"address" etc.

Categories

Resources