开发者

Concat several nodes xsl

My XML:

<?xml version="1.0"?>
<Result>
   <Answer questionId="Servicios">Auditoría|Asesoría en Impuestos|</Answer>
   <Answer questionId="Servicios">Auditoría|Outsourcing|Asesoría en RRHH|</Answer>
</Result>

I want to concat each node() into a UNIQUE variable (<xsl:variable name = "var"/> for example) using xsl:for-each or something like that, then count the "|" char using this:

<xsl:variable name="total" select="string-length(string($var))-string-length(translate(string($var),'|',''))"/>

If i do this:

    <xsl:value-of select ="//Result/Answer[@questionId = 'Servicios']//text()"/>
<!--The return is something like an array-->
<!--[1]Auditoría|Asesoría en Impuestos|-->
<!--[2]Auditoría|Outsourcing|Asesoría en RRHH|-->
<!--and the res开发者_如何学编程ult is '2' it only select the [1] and i need all of them, [1] and [2] in this case-->

I think i must concatenate all the values with xsl:for-each

im using xslt version="1.0"

I would appreciate any help! Thanks!


The shortest/simplest XSLT transformation that produces the wanted result (the concatenation of the string-values of the Answer elements) is this:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
  <xsl:value-of select="."/>
 </xsl:template>
</xsl:stylesheet>

When applied on the provided XML document:

<Result>
    <Answer questionId="Servicios">Auditoría|Asesoría en Impuestos|</Answer>
    <Answer questionId="Servicios">Auditoría|Outsourcing|Asesoría en RRHH|</Answer>
</Result>

exactly the wanted, correct result is produced:

Auditoría|Asesoría en Impuestos|Auditoría|Outsourcing|Asesoría en RRHH|

Explanation:

  1. The string value of the root node / is the concatenation of all of its text-node descendents.

  2. The <xsl:strip-space elements="*"/> directive eliminates from the XML document all unwanted whitespace-only text nodes.

Update: If the XML document is more complex than the provided one and some filtering is required, here is a general and simple solution, using the same idea:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vStrings">
  <xsl:copy-of select="/*/*[@questionId='Servicios']"/>
 </xsl:variable>

 <xsl:template match="/">
  <xsl:value-of select="$vStrings"/>
 </xsl:template>
</xsl:stylesheet>

when applied on this XML document (note that we must exclude the second <Answer>):

<Result>
    <Answer questionId="Servicios">Auditoría|Asesoría en Impuestos|</Answer>
    <Answer questionId="X">Auditoría|Outsourcing|Asesoría en RRHH|</Answer>
    <Answer questionId="Servicios">Auditoría|Outsourcing|Asesoría en RRHH|</Answer>
</Result>

again the wanted, correct result is produced:

Auditoría|Asesoría en Impuestos|Auditoría|Outsourcing|Asesoría en RRHH|


For the given document, you can concatenate pretty simple with normalize-space(Result) but note that it is not even necessary in your count code.

This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:template match="/">
        <xsl:value-of select="string-length(Result)-
            string-length(translate(Result,'|',''))"/> 
    </xsl:template>
</xsl:stylesheet>

just outputs the result '5' without even using a for-each.

UPDATE after OP's edit:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:template match="/">
        <xsl:variable name="var">
            <xsl:apply-templates select="//Answer[@questionId='Servicios']"/>
        </xsl:variable>
        <xsl:variable name="total" select="string-length($var)-
            string-length(translate($var,'|',''))"/>
        <xsl:value-of select="$total"/> 
    </xsl:template>
</xsl:stylesheet> 


<!-- This will concatenate the nodes with a comma in between.  Is this what you want?-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
    <xsl:template match="/*">
      <xsl:for-each select="Answer/text()">
        <xsl:value-of select="."/>
        <xsl:text>,</xsl:text>
      </xsl:for-each>
    </xsl:template>
  </xsl:stylesheet>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜