xml xslt 从节点连接文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4038571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 13:23:00  来源:igfitidea点击:

xslt concatenate text from nodes

xmlxsltxpathconcatenation

提问by Matt Wolfe

I have an xml file that looks like this:

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

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

keep in mind that tag names within args could be named anything (I don't know ahead of time) Now i have this xml file stored in a variable called $data which I loaded using a document() call in the xslt stylesheet (its not the backing data for the xslt file)

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

I want to take that data and produce the following output: sometag=abc&anothertag=def&atag=blah

我想获取该数据并产生以下输出: sometag=abc&anothertag=def&atag=blah

so (a very simplified verison looks like this:

所以(一个非常简化的版本看起来像这样:

<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>

This almost works but it also prints text nodes from the input file and I don't want to match text nodes..

这几乎有效,但它也从输入文件打印文本节点,我不想匹配文本节点..

回答by Dimitre Novatchev

This transformation:

这种转变

<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>

when applied on the provided XML document:

当应用于提供的 XML 文档时

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

produces the wanted, correct result:

产生想要的、正确的结果

sometag=abc&anothertag=def&atag=blah

回答by Matt Wolfe

I ended up realizing I could just use a for-each loop.. I'm not sure why I didnt use that to begin with. I'm still wondering how I could recursively iterate a list of adjacent nodes the way I was doing before (which wasn't working correctly because it was also catching text nodes and doing other weird things I couldn't understand). Here is my solution (I also added a separator variable)

我最终意识到我可以只使用 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>