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
xslt concatenate text from nodes
提问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>&</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>&</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>

