Search code examples
javaxmlxpathxmldocumentnodelist

Java Convert the NodeList to String to check for xml comments


I need to convert my Existing NodeList to String so I can check if it contains xml comments in the assertion.

Here is my xml:

<document>
<org1>
<!---- I am a comment ----->
<somenNode1> hello </somenode1>
<somenNode2> hello </somenode1>
</org1>

</document>

I have in NodeList and need to convert into string so I can check if it contains the comment.

Here is my code

public static NodeList allNodes (final Node document, final String xPath) {
        final XPathFactory factory = XPathFactory.newInstance();
        final XPath xpath = factory.newXPath();
        final NodeList result;
        try {
            final XPathExpression productXpath = xpath.compile(xPath);
            result = (NodeList)productXpath.evaluate(document, XPathConstants.NODESET);
        } catch (XPathExpressionException e) {

            throw new RuntimeException(e);
        }
        return result;
    }



 private static void verifyXpathContains (final String expected, final String xPath, org.w3c.dom.Document xmlDoc) {
NodeList nodeList = XPathUtils.allNodes(xmlDoc, xPath);

assertThat(nodeList.toString()).contains(expected);

}

Solution

  • It is relatively simple to iterate over the NodeList and get each child type, and then recursively go into the tree.

    public static List<Node> extractComments(final NodeList search) {
        List<Node> result = new ArrayList<>();
        for (int i = 0, length = search.getLength(); i < length; i++) {
            Node child = search.item(i);
            if (child.getNodeType() == Node.COMMENT_NODE) {
                result.add(child);
            }
            result.addAll(extractComments(child.getChildNodes()));
        }
        return result;
    }
    

    or if you're just interested in raw strings...

    public static List<String> extractComments(final NodeList search) {
        List<String> result = new ArrayList<>();
        for (int i = 0, length = search.getLength(); i < length; i++) {
            Node child = search.item(i);
            if (child.getNodeType() == Node.COMMENT_NODE) {
                result.add(child.getTextContent());
            }
            result.addAll(extractComments(child.getChildNodes()));
        }
        return result;
    }
    

    For your input above and this

    NodeList result = XPathUtils.allNodes(document, "*/org1");
    System.out.println(extractComments(result));
    

    The result is

    [[#comment:  I am a comment ]]
    

    I also note a number of syntax errors in your source input

    <document>
    <org1>
    <!---- I am a comment ----->      <== additional "--" is illegal inside a comment
    <somenNode1> hello </somenode1>   <== close tag should match open tag
    <somenNode2> hello </somenode1>   <== close tag should be somenNode2
    </org1>
    
    </document>