使用模板将元素的值连接到变量?

时间:2013-01-14 21:29:11

标签: xslt-2.0 xpath-2.0

需要连接以下数据。但是我收到的XML文档可以包含“零到n”个b元素。换句话说,如果没有b元素,xslt仍应正常工作示例:

 <a>
   <b1>Some</b2>
   <b2>data</b2>
   <b3>what</b3>
   <b4>need</b4>
   <b5>to</b5>
   <b6>be</b6>
   <b7>concatenated</b7>
</a>

预期结果

<a>
  <b1>Some data what need to be concatenated</b1>
</a>

我正在尝试以下构造,但我无法使其正常工作。

<xsl:variable name="details" select="//b*"/>
<xsl:for-each select="$details">
    <!-- how can I concatenate the values of the b's to a variable????-->
</xsl:for-each>
 <!-- Process the variable for further needs-->

我希望有些身体可以给我一个提示? 关心Dirk

2 个答案:

答案 0 :(得分:2)

你不能使用// b *来选择以b开头的所有元素,因为XPath总是在没有通配符的情况下进行精确匹配(可能除名称空间外)。所以你需要使用// * [starts-with(name(),“b”)]来选择b元素

然后你可以使用字符串连接函数单独在XPath中进行连接:

string-join(//*[starts-with(name(), "b")]/text(), " ")

答案 1 :(得分:1)

这么简单(完全转化):

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="@*|node()">
  <xsl:copy>
   <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="*[starts-with(name(), 'b')][1]">
  <xsl:element name="{name()}" namespace="{namespace-uri()}">
   <xsl:sequence select="../*[starts-with(name(), 'b')]/string()"/>
  </xsl:element>
 </xsl:template>
 <xsl:template match="text()[true()]| *[starts-with(name(), 'b')][position() gt 1]"/>
</xsl:stylesheet>

当对提供的(格式正确的)XML文档应用此转换时:

 <a>
   <b1>Some</b1>
   <b2>data</b2>
   <b3>what</b3>
   <b4>need</b4>
   <b5>to</b5>
   <b6>be</b6>
   <b7>concatenated</b7>
 </a>

产生了想要的正确结果

<a>
   <b1>Some data what need to be concatenated</b1>
</a>