【问题标题】:Group XML using XSLT使用 XSLT 对 XML 进行分组
【发布时间】:2012-10-12 19:02:44
【问题描述】:

我正在尝试创建一个从另一个 xml 设置的标头详细信息 XML 文档。

源xml文档:

<items>
    <item>
        <col1>H</col1>
        <col2>header1</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail1.1</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail1.2</col2>
    </item>
    <item>
        <col1>H</col1>
        <col2>header2</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail2.1</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail2.2</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail2.3</col2>
    </item>
</items>

期望的输出:

<xml>
    <transaction>
        <items>
            <item>
                <col1>H</col1>
                <col2>header1</col2>
            </item>
            <item>
                <col1>D</col1>
                <col2>detail1.1</col2>
            </item>
            <item>
                <col1>D</col1>
                <col2>detail1.2</col2>
            </item>
        </items>
    </transaction>
    <transaction>
        <items>
            <item>
                <col1>H</col1>
                <col2>header2</col2>
            </item>
            <item>
                <col1>D</col1>
                <col2>detail2.1</col2>
            </item>
            <item>
                <col1>D</col1>
                <col2>detail2.2</col2>
            </item>
            <item>
                <col1>D</col1>
                <col2>detail2.3</col2>
            </item>
        </items>
    </transaction>
</xml>

我尝试的 XSLT:

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="/ | node() | @* | comment() | processing-instruction()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="item[col1='H']">
        <transaction>
            <xsl:apply-templates/>
        </transaction>
    </xsl:template>
</xsl:transform>

【问题讨论】:

    标签: xslt-1.0


    【解决方案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="kItemByCol2Num" match="item[starts-with(col2, 'detail')]"
      use="substring-before(substring-after(col2, 'detail'), '.')"/>
    
     <xsl:key name="kItemByCol2Num" match="item[starts-with(col2, 'header')]"
      use="substring-after(col2, 'header')"/>
    
     <xsl:template match="node()|@*">
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
     </xsl:template>
    
     <xsl:template match=
     "item
       [starts-with(col2, 'header')
      and
        generate-id()
       =
        generate-id(key('kItemByCol2Num', substring-after(col2, 'header'))[1])
       ]">
      <transaction>
        <xsl:copy-of select="key('kItemByCol2Num', substring-after(col2, 'header'))"/>
      </transaction>
     </xsl:template>
     <xsl:template match="item"/>
    </xsl:stylesheet>
    

    应用于提供的 XML 文档时:

    <items>
        <item>
            <col1>H</col1>
            <col2>header1</col2>
        </item>
        <item>
            <col1>D</col1>
            <col2>detail1.1</col2>
        </item>
        <item>
            <col1>D</col1>
            <col2>detail1.2</col2>
        </item>
        <item>
            <col1>H</col1>
            <col2>header2</col2>
        </item>
        <item>
            <col1>D</col1>
            <col2>detail2.1</col2>
        </item>
        <item>
            <col1>D</col1>
            <col2>detail2.2</col2>
        </item>
        <item>
            <col1>D</col1>
            <col2>detail2.3</col2>
        </item>
    </items>
    

    产生想要的正确结果:

    <items>
       <transaction>
          <item>
             <col1>H</col1>
             <col2>header1</col2>
          </item>
          <item>
             <col1>D</col1>
             <col2>detail1.1</col2>
          </item>
          <item>
             <col1>D</col1>
             <col2>detail1.2</col2>
          </item>
       </transaction>
       <transaction>
          <item>
             <col1>H</col1>
             <col2>header2</col2>
          </item>
          <item>
             <col1>D</col1>
             <col2>detail2.1</col2>
          </item>
          <item>
             <col1>D</col1>
             <col2>detail2.2</col2>
          </item>
          <item>
             <col1>D</col1>
             <col2>detail2.3</col2>
          </item>
       </transaction>
    </items>
    

    说明

    1. 正确使用 Muenchian 方法进行分组。

    2. 正确使用密钥。

    【讨论】:

    • 它适用于提供的 xml,但我的要求是在 col1 上进行分组。我用 col2='header' 和 'detail' 组成了示例 xml,这样输出集就可以区分了。我正在尝试使用您提供的 xslt,但由于我不熟悉 key() 我仍然没有得到所需的输出。我原来的 xml 在 col2 上有不同的值,实际上它有 20 多列。
    • @gangt,他提供了“期望的输出”不是col1分组!!!如果您愿意,您可以提出一个新问题——当前形式的问题已完全回答。如果您不断在新问题中指定不是您实际拥有的数据,难怪 - 答案将相当不可用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多