当具有相同名称的键存在于不同级别时使用 XSLT 1.0 进行分组

  • 本文关键字:XSLT 于不同 存在 xslt xslt-1.0
  • 更新时间 :
  • 英文 :


我有以下输入xml:

    <?xml version="1.0" encoding="UTF-8"?>
<root>
   <results>
      <case>
         <KEY>c1</KEY>
         <issue>
            <KEY>i1</KEY>
            <id>Apple</id>
         </issue>
         <issue>
            <KEY>i1</KEY>
            <id>Orange</id>
         </issue>
         <issue>
            <KEY>i2</KEY>
            <id>Mango</id>
         </issue>
      </case>
      <case>
         <KEY>c1</KEY>
         <issue>
            <KEY>i5</KEY>
            <id>Apricot</id>
         </issue>
         <issue>
            <KEY>i5</KEY>
            <id>Blueberry</id>
         </issue>
         <issue>
            <KEY>i6</KEY>
            <id>blackberry</id>
         </issue>
      </case>
      <case>
         <KEY>c2</KEY>
         <issue>
            <KEY>i3</KEY>
            <id>Banana</id>
         </issue>
         <issue>
            <KEY>i3</KEY>
            <id>Cherry</id>
         </issue>
         <issue>
            <KEY>i4</KEY>
            <id>Grapes</id>
         </issue>
      </case>
   </results>
</root>

现在我想先按<case> <KEY>分组,然后按<issue> <KEY>分组。这个想法是按问题键和案例键对所有<issue>进行分组。 最后,我想将所有问题键相同的<id>移动到<issue>内的节点下<sourceInstance>

我的输出 xml 应如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <results>
      <case>
         <KEY>c1</KEY>
         <issue>
            <KEY>i1</KEY>
            <sources>
               <sourceInstance>
                  <id>Apple</id>
               </sourceInstance>
               <sourceInstance>
                  <id>Orange</id>
               </sourceInstance>
            </sources>
         </issue>
         <issue>
            <KEY>i2</KEY>
            <sources>
               <sourceInstance>
                  <id>Mango</id>
               </sourceInstance>
            </sources>
         </issue>
         <issue>
            <KEY>i5</KEY>
            <sources>
               <sourceInstance>
                  <id>Apricot</id>
               </sourceInstance>
               <sourceInstance>
                  <id>Blueberry</id>
               </sourceInstance>
            </sources>
         </issue>
         <issue>
            <KEY>i6</KEY>
            <sources>
               <sourceInstance>
                  <id>Apple</id>
               </sourceInstance>
               <sourceInstance>
                  <id>Orange</id>
               </sourceInstance>
            </sources>
         </issue>
      </case>
      <case>
         <KEY>c2</KEY>
         <issue>
            <KEY>i3</KEY>
            <sources>
               <sourceInstance>
                  <id>Banana</id>
               </sourceInstance>
               <sourceInstance>
                  <id>Cherry</id>
               </sourceInstance>
            </sources>
         </issue>
         <issue>
            <KEY>i4</KEY>
            <sources>
               <sourceInstance>
                  <id>Grapes</id>
               </sourceInstance>
            </sources>
         </issue>
      </case>
   </results>
</root>

我已经尝试使用以下 XSLT,但无法获得所需的 xml 输出。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="xml" indent="yes" />
   <xsl:key name="case" match="case" use="string(KEY)" />
   <xsl:key name="issue" match="case" use="concat(KEY, '|', KEY)" />
   <xsl:template match="results">
      <xsl:copy>
         <xsl:apply-templates select="case[generate-id() = generate-id(key('case', string(KEY))[1])]" mode="case" />
      </xsl:copy>
   </xsl:template>
   <xsl:template match="case" mode="case">
      <xsl:choose>
         <xsl:when test="KEY">
            <case>
               <xsl:copy-of select="KEY" />
               <xsl:apply-templates select="key('case', KEY)[generate-id() = generate-id(key('issue', concat(KEY, '|', KEY))[1])]" mode="issue" />
            </case>
         </xsl:when>
      </xsl:choose>
   </xsl:template>
   <xsl:template match="case " mode="issue">
      <xsl:choose>
         <xsl:when test="KEY">
            <issue>
               <xsl:copy-of select="KEY" />
               <sources>
                  <xsl:apply-templates select="key('issue', id)" />
               </sources>
            </issue>
         </xsl:when>
      </xsl:choose>
   </xsl:template>
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()" />
      </xsl:copy>
   </xsl:template>
   <xsl:template match="case">
      <sourceInstance>
         <id>
            <xsl:value-of select="id" />
         </id>
      </sourceInstance>
   </xsl:template>
</xsl:stylesheet>

看来我无法使用<case><issue><KEY>来构建键的正确组合,因为具有相同名称(即<KEY>(的节点存在于两个地方。

有人可以告诉我我的 XSLT 中缺少什么吗?

主要问题是密钥的定义 issue

<xsl:key name="issue" match="case" use="concat(KEY, '|', KEY)" />

您需要在此处匹配issue元素,并使用 KEY for issue 和父 case 元素的串联

<xsl:key name="issue" match="issue" use="concat(KEY, '|', ../KEY)" />

然后,要获取给定case KEY 的分组issue元素,您将这样做......

<xsl:apply-templates select="key('case', KEY)/issue[generate-id() = generate-id(key('issue', concat(KEY, '|', ../KEY))[1])]" mode="issue" />

试试这个 XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="xml" indent="yes" />
   <xsl:key name="case" match="case" use="string(KEY)" />
   <xsl:key name="issue" match="issue" use="concat(KEY, '|', ../KEY)" />
   <xsl:template match="results">
      <xsl:copy>
         <xsl:apply-templates select="case[generate-id() = generate-id(key('case', string(KEY))[1])]" mode="case" />
      </xsl:copy>
   </xsl:template>
   <xsl:template match="case" mode="case">
      <xsl:choose>
         <xsl:when test="KEY">
            <case>
               <xsl:copy-of select="KEY" />
               <xsl:apply-templates select="key('case', KEY)/issue[generate-id() = generate-id(key('issue', concat(KEY, '|', ../KEY))[1])]" mode="issue" />
            </case>
         </xsl:when>
      </xsl:choose>
   </xsl:template>
   <xsl:template match="issue" mode="issue">
      <xsl:choose>
         <xsl:when test="KEY">
            <issue>
               <xsl:copy-of select="KEY" />
               <sources>
                  <xsl:apply-templates select="key('issue', concat(KEY, '|', ../KEY))" />
               </sources>
            </issue>
         </xsl:when>
      </xsl:choose>
   </xsl:template>
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()" />
      </xsl:copy>
   </xsl:template>
   <xsl:template match="issue">
      <sourceInstance>
         <id>
            <xsl:value-of select="id" />
         </id>
      </sourceInstance>
   </xsl:template>
</xsl:stylesheet>

相关内容

  • 没有找到相关文章

最新更新