Java XPath API - get string representing subtree

2019-06-05 03:57发布

My question is not about xpath syntax, it's related to the java API surrounding xpath. Consider the following xml:

<wrapper>
    <metadata>
        <somefield>somevalue</somefield>
        <anotherfield>othervalue</anotherfield>
    </metadata>
    <data>
        <some>
            <unique>
                <xml>
                    <structure>stuff</structure>
                </xml>
            </unique>
        </some>
    </data>
</wrapper>

I can easily get the metadata fields using xpath by using the following code:

 XPath xp = XPathFactory.newInstance().newXPath();
 Node node = (Node) xp.evaluate("/wrapper/metadata/somefield", xmlDoc, XPathConstants.NODE);
 String somefield = node.getFirstChild().getNodeValue();

I am struggling with how I can get a string representing the subtree of xml starting with the <some> tag. In other words, what code do I write to get a String that when printed out, would print out the following? The xpath query would be "/wrapper/data/some", but I do not know how to utilize the xpath api appropriately.

<some>
    <unique>
        <xml>
            <structure>stuff</structure>
        </xml>
    </unique>
</some>

1条回答
We Are One
2楼-- · 2019-06-05 04:28

You simply need to transform the Node you get back from the XPathExpression to a String using a Transformer as you would if you were writing the document to a file, here is a full example:

public static void main(String[] args) throws Exception {
    final String xml = "<wrapper>\n"
            + "    <metadata>\n"
            + "        <somefield>somevalue</somefield>\n"
            + "        <anotherfield>othervalue</anotherfield>\n"
            + "    </metadata>\n"
            + "    <data>\n"
            + "        <some>\n"
            + "            <unique>\n"
            + "                <xml>\n"
            + "                    <structure>stuff</structure>\n"
            + "                </xml>\n"
            + "            </unique>\n"
            + "        </some>\n"
            + "    </data>\n"
            + "</wrapper>";
    final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes(Charsets.UTF_8)));
    final XPathExpression xpath = XPathFactory.newInstance().newXPath().compile("//some");
    final Node node = (Node) xpath.evaluate(doc, XPathConstants.NODE);
    StringWriter sw = new StringWriter();
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer transformer = tf.newTransformer();
    transformer.setOutputProperty(OutputKeys.METHOD, "xml");
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
    transformer.transform(new DOMSource(node), new StreamResult(sw));
    System.out.println(sw.toString());
}
查看更多
登录 后发表回答