1

I want to join the values of all the nodes that match an expression and have them separated by a comma. For example, the following xml should return "num1,num2,num3"

<products>
  <product>
    <id>1</id>
    <other>y</other>
    <notarget>x</notarget>
    <target>num1</target>
    <target>num2</target>
    <target>num3</target>
  </product>
</products>

The XPath /*[name()='products']/*[name()='product']/*[name()='target'] should get the elements, but I just don't understand how to join them.

6
  • If you're using xpath 2.0, you could use string-join() - for your input string-join(//target,',') results in num1,num2,num3 Commented Jan 19, 2015 at 0:31
  • @matthias_h I'm not using xpath 2.0 Commented Jan 19, 2015 at 0:44
  • I may be wrong, but I think in xpath 1.0 it's only possible if you know the number of elements and then use concat(), see e.g. stackoverflow.com/questions/17373041/… Commented Jan 19, 2015 at 0:51
  • 1
    possible duplicate of XPath to return string concatenation of qualifying child node values or Return text from several elements in one string using xPath Commented Jan 19, 2015 at 1:45
  • @kjhughes based on those answers, would the path be /*[name()='products']/*[name()='product']/*[name()='target']/text() and then concatenate on my own? I'm asking because it doesn't seem to be providing all the nodes Commented Jan 19, 2015 at 2:19

5 Answers 5

2

It can't be done in pure XPath 1.0 without some help from the host language. In fact it's difficult even with help from the host language, because XPath 1.0 has no concept of a "sequence of strings".

Sign up to request clarification or add additional context in comments.

Comments

1
<xsl:value-of select="[set of nodes]" separator="."/>

I wanted to do the same thing and solved it with the separator attribute using XSLT 2.0

Comments

0
<xsl:for-each select="/products/product/target">
  <xsl:if test="position() != 1">,</xsl:if><xsl:value-of select="text()"/>
</xsl:for-each>

You can place it inside variable if you want to reuse it later:

<xsl:variable name="concat">
  <xsl:for-each select="products/product/target">
    <xsl:if test="position() != 1">,</xsl:if><xsl:value-of select="text()"/>
  </xsl:for-each>
</xsl:variable>

<xsl:value-of select="$concat"/>

2 Comments

This would be a great answer if the question were about xslt rather than xpath...
My fault. If it's a saxon or xalan then it's rather easy to write external funtion that will return concatenated strings.
0

With saxon-lint :

saxon-lint --output-separator , --xpath '//target/text()' file

OUTPUT

num1,num2,num3

Comments

0

Use concat with your delimiter (per https://stackoverflow.com/a/25766054/148889)

concat(//SomeElement/text(),'_',//OtherElement/text())

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.