Concatenate multiple node values in xpath

131,986

Solution 1

Try this expression...

string-join(//element3/(concat(element4/text(), '.', element5/text())), "
")

Solution 2

I used concat method and works well.

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

Solution 3

Here comes a solution with XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="//element3">
    <xsl:value-of select="element4/text()" />.<xsl:value-of select="element5/text()" />
</xsl:template>
</xsl:stylesheet>

Solution 4

for $d in $doc/element2/element3 return fn:string-join(fn:data($d/element()), ".").
$doc stores the Xml.

Solution 5

If you need to join xpath-selected text nodes but can not use string-join (when you are stuck with XSL 1.0) this might help:

<xsl:variable name="x">
    <xsl:apply-templates select="..." mode="string-join-mode"/>
</xsl:variable>
joined and normalized: <xsl:value-of select="normalize-space($x)"/>

<xsl:template match="*" mode="string-join-mode">
    <xsl:apply-templates mode="string-join-mode"/>
</xsl:template>    

<xsl:template match="text()" mode="string-join-mode">
    <xsl:value-of select="."/>
</xsl:template>    
Share:
131,986

Related videos on Youtube

krishna2642
Author by

krishna2642

Merge Keep

Updated on July 05, 2020

Comments

  • krishna2642
    krishna2642 almost 4 years

    I have a XML that looks like this

    <element1>
        <element2>
            <element3>    
                <element4>Hello</element4>
                <element5>World</element5>
            </element3>
            <element3>    
                <element4>Hello2</element4>
                <element5>World2</element5>
            </element3>
            <element3>    
                <element4>Hello3</element4>
                <element5>World3</element5>
            </element3>
        </element2>
    </element1>
    

    I am trying to use Xpath to get a result like this:

    Hello.World
    Hello2.World2
    Hello3.World3
    

    I used concat function below but I did not get correct result.

    Concat function:

    concat(/element1/element2/element3/element4/text(),".", /element1/element2/element3/element5/text())
    

    Result I got:

    Hello.World
    

    How can I get the correct result? I am using XPath with Camel Spring DSL.

    Edit:

    Solutions in XQuery, XSLT and SPel are also appreciated.

    Edit

    I tried string-join and it did not work:

    string-join function:

    string-join((/element1/element2/element3/element4/text(), /element1/element2/element3/element5/text()),".")
    

    Result I got:

    Hello.Hello2.Hello3.World.World2.World3
    
    • hek2mgl
      hek2mgl about 10 years
      In XPath2.0 there is string-join, looks more appropriate there.. However, what is with XSLT? I would use that here.
    • krishna2642
      krishna2642 about 10 years
      Added edit for string-join function. Also added XSLT to tags and requested solution.
    • nwellnhof
      nwellnhof about 10 years
      To understand why you get this result: A node-set is converted to a string by returning the string-value of the node in the node-set that is first in document order.
  • adamretter
    adamretter about 10 years
    If you want a Sequence of results, the more succinct way is to use //element3/string-join(element4 | element5, "."), and if you must have a single string as a result then, string-join(//element3/string-join(element4 | element5, "."), "&#xa;") is another formulation, which IMHO is more readable.
  • hek2mgl
    hek2mgl over 7 years
    What's the point of down-voting this? Note that string-join() is available only for XPath2.0. That's why I suggested to use XSLT
  • thewaywewere
    thewaywewere almost 7 years
    Just posting code is not a good answer. Please read this how-to-answer if you haven't read it.
  • Timmah
    Timmah almost 2 years
    +1 for the //el/string-join(el2 | el3, 'separator'). I used this to scrape images and generate a CSV: //img/string-join(@src | @alt | @width | @height, '|')