xslt连接节点中的文本

时间:2010-10-27 23:37:19

标签: xml xslt xpath concatenation

我有一个xml文件,如下所示:

<args>
  <sometag value="abc" />
  <anothertag value="def" />
  <atag value="blah" />
</args>

请记住,args中的标记名称可以命名为任何名称(我不知道提前) 现在我将这个xml文件存储在一个名为$ data的变量中,我使用xslt样式表中的document()调用加载它(它不是xslt文件的后备数据)

我想获取该数据并生成以下输出: 的 sometag = ABC&安培; anothertag = DEF&安培; ATAG =嗒嗒

所以(非常简化的verison看起来像这样:

<xsl:template>
 <xsl:variable name="data"  select="document('/path/to/xml')" />

  <xsl:call-template name='build_string'>
    <xsl:with-param name='data' select='$data' />

  </xsl:call-template>

</xsl:template>

<!-- here is where i need help -->
<xsl:template name="build_string">
  <xsl:param name='data'>
  <xsl:value-of select='name($data/.)' />=<xsl:value-of select='$data/@value' />

  <xsl:if test='$data/following-sibling::node()'>
    <xsl:text>&#38;</xsl:text>
    <xsl:call-template name="build_str">
     <xsl:with-param name="data" select='$nodes/following-sibling::node()' />
    </xsl:call-template>
  </xsl:if>


</xsl:template>

这几乎可以工作,但它也会从输入文件打印文本节点,我不想匹配文本节点..

2 个答案:

答案 0 :(得分:14)

此转化

<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="concat(name(),'=',@value)"/>

  <xsl:if test="not(position()=last())">
    <xsl:text>&amp;</xsl:text>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<args>
  <sometag value="abc"/>
  <anothertag value="def"/>
  <atag value="blah"/>
</args>

生成想要的正确结果

sometag=abc&anothertag=def&atag=blah

答案 1 :(得分:3)

我最终意识到我可以使用for-each循环.. 我不确定为什么我没有使用它开始。我仍然想知道如何递归迭代相邻节点的列表,就像我之前做的那样(因为它也在捕捉文本节点并做其他我不理解的奇怪事情,因此无法正常工作)。 这是我的解决方案(我还添加了一个分隔符变量)

<xsl:template name='string_builder'>
    <xsl:param name='data' />
    <xsl:param name='separator' />        
    <xsl:for-each select='$data/*'>
        <xsl:value-of select='name()'/>=<xsl:value-of select='@value'/>
        <xsl:if test='position() != last()'>
           <xsl:value-of select='$separator'/>
        </xsl:if>
    </xsl:for-each>
</xsl:template>