0

我有一个这样的节点集合

<node id="1">
  <languaje>c</languaje>
  <os>linux</os> 
</node>
<node id="2">
  <languaje>c++</languaje>
  <os>linux</os> 
</node>
<node id="3">
  <languaje>c#</languaje>
  <os>window</os> 
</node>
<node id="4">
  <languaje>basic</languaje>
  <os>mac</os> 
</node>

我想创建一个像这样的所有属性 id 的新集合

<root>
 <token>1</token>
 <token>2</token>
 <token>3</token>
 <token>4</token>
</root>

怎么能这样

4

3 回答 3

1

所有你需要的是

<xsl:output indent="yes"/>

<xsl:template match="*[node]">
  <root>
    <xsl:apply-templates select="node"/>
  </root>
</xsl:template>

<xsl:template match="node">
  <token><xsl:value-of select="@id"/></token>
</xsl:template>

如果要将结果存储在变量中,可以使用 XSLT 1.0 创建结果树片段,例如

<xsl:variable name="rtf1">
  <xsl:apply-templates select="node()" mode="m1"/>
</xsl:variable>

    <xsl:template match="*[node]" mode="m1">
      <root>
        <xsl:apply-templates select="node" mode="m1"/>
      </root>
    </xsl:template>

    <xsl:template match="node" mode="m1">
      <token><xsl:value-of select="@id"/></token>
    </xsl:template>

然后您可以<xsl:copy-of select="$rtf1"/>使用结果树片段,或者使用“exsl:node-set”,您可以使用 XPath 和 XSLT 处理创建的节点,例如

<xsl:apply-templates select="exsl:node-set($rtf1)/root/token"/>

使用 XSLT 2.0 不再有结果树片段,因此您可以像使用任何输入一样使用变量,而无需扩展函数。

于 2012-07-24T17:05:39.380 回答
1

如果您可以使用 XQuery,您可以这样做:

<root>
   { ($document/node/<node>{string(@id)}</node>) }
</root>

这是最清晰的解决方案。

否则,您可以通过连接标签和您的 ids 来使用 XPath 2 创建一个包含所需结果的字符串(不是文档):

concat("<root>", string-join(for $i in /base/node/@id return concat("<node>",$i,"</node>"), " ") , "</root>")
于 2012-07-24T17:07:51.567 回答
0

如果将所有节点包装在标签下,例如 <nodes> ,则可以:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<root>
  <xsl:apply-templates select="*" />
</root>
</xsl:template>

<!-- templates -->
  <xsl:template match="node">
  <token><xsl:value-of select="@id" /></token>
</xsl:template>
</xsl:stylesheet>

在 XsltCake 上测试

http://www.xsltcake.com/slices/E937yH

于 2012-07-24T17:23:27.897 回答