0

我在嵌套元素的 Muenchian 方法之前问了一个类似的问题,但这次问题不同。我的 xml 输入是-

<?xml version="1.0" encoding="UTF-8"?> 
<foo>  <bar>bar</bar> 
       <bar>bar</bar> 
       <foobar>
               <baz>baz</baz>
               <baz>baz</baz>
      </foobar>
       <foobar>foobar</foobar>
</foo>

使用 xslt 的输出应该是

 <?xml version="1.0" encoding="UTF-8"?>

 <foo>  
 <s> 
 <s> 
 <bar>bar</bar>  
 <bar>bar</bar>
 </s>
 <s> 
 <foobar>
 <s>
 <baz>baz</baz>
 <baz>baz</baz>
  </s>
</foobar>
 <foobar>foobar></foobar>
 </s> 
 </s>
</foo>

如果任何后代元素按顺序排列,则代码也应将它们放在 s 标记中。放置元素(不是后代元素)的 xslt 文件是 -

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

  <xsl:key name="kGroupLeader" match="*" use="generate-id(self::*[name() != name(preceding-sibling::*[1])])
   " />

<xsl:template match="*/">
<xsl:copy>
  <s>
    <xsl:for-each select="*[key('kGroupLeader', generate-id())]">
      <s>
        <xsl:copy-of select=". | following-sibling::*[
          name() = name(current())
          and
          generate-id(current()) = generate-id(
            preceding-sibling::*[key('kGroupLeader', generate-id())][1]
          )
        ]" />
      </s>
    </xsl:for-each>
  </s>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

我使用了 descendant-or-self::* 而不是 * 但没有得到正确的输出。可能是什么解决方案。非常感谢。

4

1 回答 1

1

首先,您可以将根元素上的匹配更改为任何带有子元素的更通用的匹配

 <xsl:template match="*[*]">

在这种情况下,您不需要创建最外层的 s元素,但您仍将像以前一样使用xsl:for-each迭代“组领导”,但您将使用xsl代替xsl:copy-of :apply-templates以便递归调用模板,使其可用于后代元素。

试试这个 XSLT

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

    <xsl:key name="kGroupLeader" match="*" 
             use="generate-id(self::*[name() != name(preceding-sibling::*[1])])" />

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

    <xsl:template match="*[*]">
        <xsl:copy>
            <xsl:for-each select="*[key('kGroupLeader', generate-id())]">
              <s>
                <xsl:apply-templates select=". | following-sibling::*[
                      name() = name(current())
                      and generate-id(current()) = generate-id(
                        preceding-sibling::*[key('kGroupLeader', generate-id())][1]
                      )
                    ]" />
              </s>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

请注意此处使用身份模板来复制文档中的所有其他节点。

编辑:注意,我不完全确定这算作 Muenchian 分组,因为键仅包含每个“组”中的第一个元素,而不是需要被s元素包围的所有元素。

这是使用 Muenchian 分组的替代 XSLT,具有相同名称的连续元素形成每个组。(并且键使用组中第一个元素的 id 来查找它们)。

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

    <xsl:key name="kGroupLeader" match="*" 
             use="generate-id((self::*|preceding-sibling::*)[name() != name(preceding-sibling::*[1])][last()])" />

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

    <xsl:template match="*[*]">
        <xsl:copy>
            <xsl:for-each select="*[name() != name(preceding-sibling::*[1])]">
              <s>
                <xsl:apply-templates select="key('kGroupLeader', generate-id())" />
              </s>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
于 2014-03-24T08:43:40.050 回答