XSLT编号 - 分组?

时间:2011-12-18 10:49:25

标签: xslt

我正在尝试执行以下操作:

<body>
    <div>
        <p> text<note/>texttext<note/>text </p>
        <p> text<note/>text </p>
    </div>
    <div>
        text<note/>texttext<note/>text
    </div>
</body>

应该导致

<body>
    <div>
        <p> text<note n="1"/>texttext<note n="2"/>text </p>
        <p> text<note n="3"/>text </p>
    </div>
    <div>
        text<note n="1"/>texttext<note n="2"/>text
    </div>
</body>

如您所见,我想对div下的所有注释进行编号,而不管父节点如何。因此,注释可以以任何方式在div下构建。 但是我无法通过使用xsl:number来找出解决方案。任何帮助将不胜感激。

编辑:非常感谢DRCB的解决方案。我已经对它进行了调整,以便它也可以通过使用身份模板用于复杂的嵌套。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="div//note">
    <note>
        <xsl:attribute name="n">
            <xsl:value-of select="count(preceding::note) - count(preceding::div//note) + 1"/>
        </xsl:attribute>
        <xsl:value-of select="."/>
    </note>
</xsl:template>


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

</xsl:stylesheet>

tranforms:

<body>
    <any>
        <div>
            <p>
                <p> text<note/>texttext<note/>text </p>
            </p>
            <p> text<note/>text </p>
        </div>
    </any>
    <div> text<note/>texttext<note/>text </div>
</body>

为:

<body>
    <any>
        <div>
            <p>
                <p> text<note n="1"/>texttext<note n="2"/>text </p>
            </p>
            <p> text<note n="3"/>text </p>
        </div>
    </any>
    <div> text<note n="1"/>texttext<note n="2"/>text </div>
</body>

我相信可能有更好的解决方案,但这对我有用。

2 个答案:

答案 0 :(得分:1)

我找到了以下快速解决方法:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by http://www.w3schools.com/xsl/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalogp -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="div">
  [div <xsl:apply-templates/>]
</xsl:template>

<xsl:template match="note">
  [note n=<xsl:value-of select="count(preceding::note) - count(preceding::div//note) + 1"/>]
</xsl:template>
</xsl:stylesheet>

但是它只适用于没有复杂嵌套的“普通”div结构。

您可以在此处测试:http://www.w3schools.com/xsl/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog与您的源xml。

答案 1 :(得分:1)

使用xsl:number的解决方案:

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

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

 <xsl:template match="note">
  <xsl:variable name="vNum">
   <xsl:number level="any" count="note" from="/*/div"/>
  </xsl:variable>
  <note n="{$vNum}">
   <xsl:apply-templates/>
  </note>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时

<body>
 <div>
  <p> text<note/>texttext<note/>text </p>
  <p> text<note/>text </p>
 </div>
 <div>
  text<note/>texttext<note/>text
 </div>
</body>

产生了想要的正确结果

<body>
   <div>
      <p> text<note n="1"/>texttext<note n="2"/>text </p>
      <p> text<note n="3"/>text </p>
   </div>
   <div>
  text<note n="1"/>texttext<note n="2"/>text
 </div>
</body>

解释:正确使用from的{​​{1}}属性。