2

问题与此类似, Dimitre 已回答的较早问题。响应 xml 中略有修改。然而这一次,我们需要从重复块中提取一个元素。不确定我们是否可以在这里使用 xsl 键功能。

我的输入xml

<M>
   <a>
      <b>
         <c f="123">
            <key>Al</key>
            <e NO="678">
               <f>Y</f>
               <g>
                  <h>FTO</h>
               </g>
            </e>
         </c>
      </b>
   </a>
   <a>
      <b>
         <c f="123">
            <key>Al</key>
            <e NO="678">
               <f>Y</f>
               <g>
                  <h>FTO</h>
               </g>
            </e>
         </c>
      </b>
   </a>
   <a>
      <b>
         <c f="567">
            <key>Al</key>
            <e NO="678">
               <f>Y</f>
               <g>
                  <h>FTO</h>
               </g>
            </e>
         </c>
      </b>
   </a>
   <a>
      <b>
         <somethingelse/>
      </b>
   </a>
</M>

我想要的输出 xml - 请注意,除了删除重复项之外,我们还需要从重复块中获取关键元素。它可能相同也可能不同。

<M>
   <a>
      <b>
         <c f="123">
            <key>Al</key>
            <key>Al</key>
            <e NO="678">
               <f>Y</f>
               <g>
                  <h>FTO</h>
               </g>
            </e>
         </c>
      </b>
   </a>
   <a>
      <b>
         <c f="567">
            <key>Al</key>
            <e NO="678">
               <f>Y</f>
               <g>
                  <h>FTO</h>
               </g>
            </e>
         </c>
      </b>
   </a>
   <a>
      <b>
         <somethingelse/>
      </b>
   </a>
</M>
4

1 回答 1

1

这种转变

<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:key name="kAByC-F" match="a" use="*/c/@f"/>

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

         <xsl:template match=
          "a[*/c
           and
             not(generate-id()
                =
                 generate-id(key('kAByC-F', */c/@f)[1])
                 )
            ]"/>

         <xsl:template match="a/b/c[@f]">
          <c f="{@f}">
            <xsl:apply-templates select="key('kAByC-F', @f)/b/c/key"/>
            <xsl:apply-templates select="*[not(self::key)]"/>
          </c>
         </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时

<M>
    <a>
        <b>
            <c f="123">
                <key>Al</key>
                <e NO="678">
                    <f>Y</f>
                    <g>
                        <h>FTO</h>
                    </g>
                </e>
            </c>
        </b>
    </a>
    <a>
        <b>
            <c f="123">
                <key>Al</key>
                <e NO="678">
                    <f>Y</f>
                    <g>
                        <h>FTO</h>
                    </g>
                </e>
            </c>
        </b>
    </a>
    <a>
        <b>
            <c f="567">
                <key>Al</key>
                <e NO="678">
                    <f>Y</f>
                    <g>
                        <h>FTO</h>
                    </g>
                </e>
            </c>
        </b>
    </a>
    <a>
        <b>
            <somethingelse/>
        </b>
    </a>
</M>

产生想要的正确结果

<M>
   <a>
      <b>
         <c f="123">
            <key>Al</key>
            <key>Al</key>
            <e NO="678">
               <f>Y</f>
               <g>
                  <h>FTO</h>
               </g>
            </e>
         </c>
      </b>
   </a>
   <a>
      <b>
         <c f="567">
            <key>Al</key>
            <e NO="678">
               <f>Y</f>
               <g>
                  <h>FTO</h>
               </g>
            </e>
         </c>
      </b>
   </a>
   <a>
      <b>
         <somethingelse/>
      </b>
   </a>
</M>

说明

  1. 身份规则“按原样”复制每个节点。它被两个匹配特定节点的模板覆盖。

  2. 第一个覆盖模板删除所有不是使用键( Muenchian 分组方法)指定a的第一个元素的元素。a

  3. 第二个覆盖模板匹配并处理c未删除(由第一个覆盖模板)元素的孙子a元素。

于 2012-06-15T04:42:45.793 回答