Reputation: 1203
based on xpath i want to select a part of xml and selected part i want to use as another xml source.
e.g:
<root>
<a type="t1">
<property name="data" value="val1"/>
</a>
<a type="t2">
<property name="data" value="val2"/>
</a>
<a type="t1">
<property name="data" value="val2"/>
</a>
</root>
xpath : /root/a[@type="t1"]/
and selected xml would be
<root>
<a type="t1">
<property name="data" value="val1"/>
</a>
<a type="t1">
<property name="data" value="val2"/>
</a>
</root>
same i want to use as another xml source in java. Please help me out.
Upvotes: 1
Views: 4238
Reputation: 2456
Following function can be used to extract xml block as string by passing proper xpath expression,
private static String nodeToString(Node node) throws TransformerException
{
StringWriter buf = new StringWriter();
Transformer xform = TransformerFactory.newInstance().newTransformer();
xform.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
xform.transform(new DOMSource(node), new StreamResult(buf));
return(buf.toString());
}
public static void main(String[] args) throws Exception
{
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(inputFile);
XPath xPath = XPathFactory.newInstance().newXPath();
Node result = (Node)xPath.evaluate("A/B/C", doc, XPathConstants.NODE); //"A/B[id = '1']" //"//*[@type='t1']"
System.out.println(nodeToString(result));
}
Upvotes: 1
Reputation: 347204
Load the XML and find the nodes you are looking for...
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
DocumentBuilder b = f.newDocumentBuilder();
Document d = b.parse(...);
// Find all nodes with the attribute of type equal to `t1`
// You could use //*/a[@type='t1'] if you wanted to narrow it down
// This find ALL matches through out the document...
String expression = "//*[@type='t1']";
XPath xPath = XPathFactory.newInstance().newXPath();
Object result = xPath.compile(expression).evaluate(d, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
Create a new Document
....
Document d2 = b.newDocument();
Element root = d2.createElement("root");
d2.appendChild(root);
Add the nodes from the first to the second...
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
d2.adoptNode(node);
root.appendChild(node);
}
Which should result in...
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<a type="t1">
<property name="data" value="val1"/>
</a>
<a type="t1">
<property name="data" value="val2"/>
</a>
</root>
Upvotes: 1