0

I'm trying to extract values from <to> multiple nodes using XPath but what I have got is only first value

SOAP looks like:

<addressBlock xmlns:i="http://www.w3.org/2001/XMLSchema-instance" s:relay="1">
    <from>mailto:user1@test.local</from>
    <to>mailto:user2@test.local</to>
    <to>mailto:user3@test2.local</to>
</addressBlock>

My code looks like:

private String extractFieldFromXml(Document doc, XPath xPath, String expression)
{
    try
    {
        Node node = (Node) xPath.compile(expression).evaluate(doc, XPathConstants.NODE);
        return node == null ? null : node.getTextContent();
    } catch (XPathExpressionException e)
    {
        log.info(e.getMessage());
        return null;
    }

}

Then I have tried to do that:

String to = extractFieldFromXml(doc, xpath, msgExpression);

for (Iterator<String> to = to.iterator(); to.hasNext();) {
   String value = to.next();
   System.out.println(value);
}
JackTheKnife
  • 3,795
  • 8
  • 57
  • 117

2 Answers2

1

The XPath to get all to values is

/addressBlock/to

This expression returns a concatenation of to/text() strings.
Use Java to run a for-each over all items of this result.

zx485
  • 28,498
  • 28
  • 50
  • 59
  • And what is an iterator in this case? I have updated my question with the code which extracts values for selected node. – JackTheKnife Apr 18 '18 at 17:57
  • 1
    I'm sorry, I cannot test it at the moment. But one approach can be [described in this SO answer](https://stackoverflow.com/a/3350654/1305969). So evaluate the XPath to a `NodeList` and pass that to the iterator - so operate on `Node`s instead of `String`s and get the text content only at the last step. – zx485 Apr 18 '18 at 18:14
  • Yeah, that make a sense. I will try that approach and update with results. – JackTheKnife Apr 18 '18 at 18:17
1

In case if somebody is going to looking for solution working code is below:

private String extractFieldFromXml(Document doc, XPath xPath, String expression)
{
    if (expression.equals(RECIPIENT_EXPRESSION)) {
        try
        {
            NodeList nodes = (NodeList) xPath.evaluate(expression,doc, XPathConstants.NODESET);

            ArrayList<String> recipientsList = new ArrayList<String>();

            for (int i = 0; i < nodes.getLength(); i++){

                Node node = nodes.item(i);
                if (node != null) {
                    String recipient = node.getTextContent();
                    recipientsList.add(recipient);
                }
            }

            String recipients = StringUtils.join(recipientsList,",");
            return recipients == null ? null: recipients;

        } catch (XPathExpressionException e)
        {
            log.info(e.getMessage());
            return null;
        }
    }
    else {
        try
        {
            Node node = (Node) xPath.compile(expression).evaluate(doc, XPathConstants.NODE);
            return node == null ? null : node.getTextContent();
        } catch (XPathExpressionException e)
        {
            log.info(e.getMessage());
            return null;
        }
    }
}
JackTheKnife
  • 3,795
  • 8
  • 57
  • 117