使用XSLT将多层XML转换为平面XML

使用XSLT将多层XML转换为平面XML,xml,xslt,Xml,Xslt,我正在将相同的多标记元素转换为不同的记录。 在本文中,我使用的是XSLT。 我需要XSLT方面的帮助。 我得到的第一个标签结果是正确的,我不知道为什么第二个标签没有得到 说明:: *在第一张CD中::从一个列表到多个标题。我想根据标题将其拆分为不同的标签。 在第二张CD中:第一位艺术家的第一个标题和第二位艺术家的第二个标题。我还需要基于标题和艺术家的不同(两)个CD标签。[第一个标题第一个艺术家和第二个标题第二个艺术家]。 我的源XML如下所示: <?xml version="1.0" e

我正在将相同的多标记元素转换为不同的记录。 在本文中,我使用的是XSLT。 我需要XSLT方面的帮助。 我得到的第一个标签结果是正确的,我不知道为什么第二个标签没有得到

说明:: *在第一张CD中::从一个列表到多个标题。我想根据标题将其拆分为不同的标签。 在第二张CD中:第一位艺术家的第一个标题和第二位艺术家的第二个标题。我还需要基于标题和艺术家的不同(两)个CD标签。[第一个标题第一个艺术家和第二个标题第二个艺术家]。

我的源XML如下所示:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<catalog>
    <cd>
        <title>Burlesque</title>        
        <title>Empire</title>
        <title>Emp</title>
        <title>Em</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
    <cd>
        <title>Hide your</title>
        <title>heart</title>
        <artist>Bonnie</artist>
        <artist> Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
    <cd>
        <title/>
        <artist>Dolly Parton</artist>
        <country>USA</country>
        <company>RCA</company>
        <price>9.90</price>
        <year>1982</year>
    </cd>
</catalog>

滑稽
帝国
电磁脉冲
相对长度单位
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
隐藏你的
心
邦妮
泰勒
英国
哥伦比亚唱片公司
9.90
1988
多莉·帕顿
美国
RCA
9.90
1982
XSLT::

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  >
    <xsl:output method="xml" indent="yes"/>
    <xsl:key name="k" match="title" use="text()"/>
    <xsl:key name="l" match="artist" use="text()"/>
            <xsl:template match="/">
        <catalog>
            <xsl:apply-templates select="//cd/title | artist[not(node() = preceding-sibling::node())]"/>
        </catalog>
    </xsl:template>
    <xsl:template match="//cd">
        <xsl:param name="title" select="title"/>
        <xsl:param name="artist" select="artist"/>
        <cd>
            <xsl:copy-of select="key('k', $title)[not(node() = preceding-sibling::node())]"/>
            <xsl:copy-of select="key('l', $artist)[not(node() = preceding-sibling::node())]"/>
            <xsl:copy-of select="./*[name() != 'title' and 'artist']"/>
        </cd>
    </xsl:template>
    <xsl:template match="title">
            <xsl:apply-templates select="..">
            <xsl:with-param name="title" select="."/>
        </xsl:apply-templates>
    </xsl:template>
</xsl:stylesheet>

我得到的是:

<?xml version="1.0" encoding="utf-8"?>
<catalog>
  <cd>
    <title>Burlesque</title>
    <artist>Bob Dylan</artist>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
  <cd>
    <title>Empire</title>
    <artist>Bob Dylan</artist>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
  <cd>
    <title>Emp</title>
    <artist>Bob Dylan</artist>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
  <cd>
    <title>Em</title>
    <artist>Bob Dylan</artist>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
  <cd>
    <title>Hide your</title>
    <artist>Bonnie</artist>
    <artist> Tyler</artist>
    <artist>Bonnie</artist>
    <artist> Tyler</artist>
    <country>UK</country>
    <company>CBS Records</company>
    <price>9.90</price>
    <year>1988</year>
  </cd>
  <cd>
    <title>heart</title>
    <artist>Bonnie</artist>
    <artist> Tyler</artist>
    <artist>Bonnie</artist>
    <artist> Tyler</artist>
    <country>UK</country>
    <company>CBS Records</company>
    <price>9.90</price>
    <year>1988</year>
  </cd>
  <cd>
    <artist>Dolly Parton</artist>
    <artist>Dolly Parton</artist>
    <country>USA</country>
    <company>RCA</company>
    <price>9.90</price>
    <year>1982</year>
  </cd>
 </catalog>

滑稽
鲍勃·迪伦
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
帝国
鲍勃·迪伦
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
电磁脉冲
鲍勃·迪伦
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
相对长度单位
鲍勃·迪伦
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
隐藏你的
邦妮
泰勒
邦妮
泰勒
英国
哥伦比亚唱片公司
9.90
1988
心
邦妮
泰勒
邦妮
泰勒
英国
哥伦比亚唱片公司
9.90
1988
多莉·帕顿
多莉·帕顿
美国
RCA
9.90
1982
我需要的是:

<?xml version="1.0" encoding="utf-8"?>
<catalog>
  <cd>
    <title>Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
  <cd>
    <title>Empire</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
  <cd>
    <title>Emp</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
  <cd>
    <title>Em</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
  <cd>
    <title>Hide your</title>
    <artist>Bonnie</artist>
    <country>UK</country>
    <company>CBS Records</company>
    <price>9.90</price>
    <year>1988</year>
  </cd>
  <cd>
    <title>heart</title>
    <artist> Tyler</artist>
    <country>UK</country>
    <company>CBS Records</company>
    <price>9.90</price>
    <year>1988</year>
  </cd>
  <cd>
    <artist>Dolly Parton</artist>
    <artist>Dolly Parton</artist>
    <country>USA</country>
    <company>RCA</company>
    <price>9.90</price>
    <year>1982</year>
  </cd>
</catalog>

滑稽
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
帝国
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
电磁脉冲
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
相对长度单位
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
隐藏你的
邦妮
英国
哥伦比亚唱片公司
9.90
1988
心
泰勒
英国
哥伦比亚唱片公司
9.90
1988
多莉·帕顿
多莉·帕顿
美国
RCA
9.90
1982

有人能帮我吗?

这是一个的应用程序,其中参数设置为所需的叶节点,并进行次要后处理以从结果中删除两个顶部包装节点并重新包装:

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

     <xsl:param name="pLeafNodes" select="/*/*/title"/>

     <xsl:template match="/">
      <xsl:variable name="vrtfResult">
        <xsl:call-template name="StructRepro"/>
      </xsl:variable>

      <catalog>
       <xsl:copy-of select="ext:node-set($vrtfResult)/catalog/node()"/>
      </catalog>
     </xsl:template>

     <xsl:template name="StructRepro">
       <xsl:param name="pLeaves" select="$pLeafNodes"/>

       <xsl:for-each select="$pLeaves">
         <xsl:apply-templates mode="build" select="/*">
          <xsl:with-param name="pChild" select="."/>
          <xsl:with-param name="pLeaves" select="$pLeaves"/>
         </xsl:apply-templates>
       </xsl:for-each>
     </xsl:template>

      <xsl:template mode="build" match="node()|@*">
          <xsl:param name="pChild"/>
          <xsl:param name="pLeaves"/>

         <xsl:copy>
           <xsl:apply-templates mode="build" select="@*"/>

           <xsl:variable name="vLeafChild" select=
             "*[count(.|$pChild) = count($pChild)]"/>

           <xsl:choose>
            <xsl:when test="$vLeafChild">
             <xsl:apply-templates mode="build"
                 select="$vLeafChild
                        |
                          node()[not(count(.|$pLeaves) = count($pLeaves))]">
                 <xsl:with-param name="pChild" select="$pChild"/>
                 <xsl:with-param name="pLeaves" select="$pLeaves"/>
             </xsl:apply-templates>
            </xsl:when>
            <xsl:otherwise>
             <xsl:apply-templates mode="build" select=
             "node()[not(.//*[count(.|$pLeaves) = count($pLeaves)])
                    or
                     .//*[count(.|$pChild) = count($pChild)]
                    ]
             ">

                 <xsl:with-param name="pChild" select="$pChild"/>
                 <xsl:with-param name="pLeaves" select="$pLeaves"/>
             </xsl:apply-templates>
            </xsl:otherwise>
           </xsl:choose>
         </xsl:copy>
     </xsl:template>
     <xsl:template match="text()"/>
</xsl:stylesheet>
当此转换应用于同一XML文档(如上)时,结果现在满足附加要求

<catalog>
    <cd>
        <title>Burlesque</title>
        <title>Empire</title>
        <title>Emp</title>
        <title>Em</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
    <cd>
        <title>Hide your</title>
        <title>heart</title>
        <artist>Bonnie</artist>
        <artist> Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
    <cd>
        <title/>
        <artist>Dolly Parton</artist>
        <country>USA</country>
        <company>RCA</company>
        <price>9.90</price>
        <year>1982</year>
    </cd>
</catalog>
<catalog>
   <cd>
      <title>Burlesque</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Empire</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Emp</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Em</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Hide your</title>
      <artist>Bonnie</artist>
      <artist> Tyler</artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
   </cd>
   <cd>
      <title>heart</title>
      <artist>Bonnie</artist>
      <artist> Tyler</artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
   </cd>
   <cd>
      <title/>
      <artist>Dolly Parton</artist>
      <country>USA</country>
      <company>RCA</company>
      <price>9.90</price>
      <year>1982</year>
   </cd>
</catalog>
<catalog>
   <cd>
      <title>Burlesque</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Empire</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Emp</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Em</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Hide your</title>
      <artist>Bonnie</artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
   </cd>
   <cd>
      <title>heart</title>
      <artist> Tyler</artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
   </cd>
   <cd>
      <title/>
      <artist>Dolly Parton</artist>
      <country>USA</country>
      <company>RCA</company>
      <price>9.90</price>
      <year>1982</year>
   </cd>
</catalog>

滑稽
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
帝国
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
电磁脉冲
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
相对长度单位
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
隐藏你的
邦妮
英国
哥伦比亚唱片公司
9.90
1988
心
泰勒
英国
哥伦比亚唱片公司
9.90
1988
多莉·帕顿
美国
RCA
9.90
1982

这是一个的应用程序,其中参数设置为所需的叶节点,并进行次要后处理以从结果中删除两个顶部包装节点并重新包装:

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

     <xsl:param name="pLeafNodes" select="/*/*/title"/>

     <xsl:template match="/">
      <xsl:variable name="vrtfResult">
        <xsl:call-template name="StructRepro"/>
      </xsl:variable>

      <catalog>
       <xsl:copy-of select="ext:node-set($vrtfResult)/catalog/node()"/>
      </catalog>
     </xsl:template>

     <xsl:template name="StructRepro">
       <xsl:param name="pLeaves" select="$pLeafNodes"/>

       <xsl:for-each select="$pLeaves">
         <xsl:apply-templates mode="build" select="/*">
          <xsl:with-param name="pChild" select="."/>
          <xsl:with-param name="pLeaves" select="$pLeaves"/>
         </xsl:apply-templates>
       </xsl:for-each>
     </xsl:template>

      <xsl:template mode="build" match="node()|@*">
          <xsl:param name="pChild"/>
          <xsl:param name="pLeaves"/>

         <xsl:copy>
           <xsl:apply-templates mode="build" select="@*"/>

           <xsl:variable name="vLeafChild" select=
             "*[count(.|$pChild) = count($pChild)]"/>

           <xsl:choose>
            <xsl:when test="$vLeafChild">
             <xsl:apply-templates mode="build"
                 select="$vLeafChild
                        |
                          node()[not(count(.|$pLeaves) = count($pLeaves))]">
                 <xsl:with-param name="pChild" select="$pChild"/>
                 <xsl:with-param name="pLeaves" select="$pLeaves"/>
             </xsl:apply-templates>
            </xsl:when>
            <xsl:otherwise>
             <xsl:apply-templates mode="build" select=
             "node()[not(.//*[count(.|$pLeaves) = count($pLeaves)])
                    or
                     .//*[count(.|$pChild) = count($pChild)]
                    ]
             ">

                 <xsl:with-param name="pChild" select="$pChild"/>
                 <xsl:with-param name="pLeaves" select="$pLeaves"/>
             </xsl:apply-templates>
            </xsl:otherwise>
           </xsl:choose>
         </xsl:copy>
     </xsl:template>
     <xsl:template match="text()"/>
</xsl:stylesheet>
当此转换应用于同一XML文档(如上)时,结果现在满足附加要求

<catalog>
    <cd>
        <title>Burlesque</title>
        <title>Empire</title>
        <title>Emp</title>
        <title>Em</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
    <cd>
        <title>Hide your</title>
        <title>heart</title>
        <artist>Bonnie</artist>
        <artist> Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
    <cd>
        <title/>
        <artist>Dolly Parton</artist>
        <country>USA</country>
        <company>RCA</company>
        <price>9.90</price>
        <year>1982</year>
    </cd>
</catalog>
<catalog>
   <cd>
      <title>Burlesque</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Empire</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Emp</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Em</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Hide your</title>
      <artist>Bonnie</artist>
      <artist> Tyler</artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
   </cd>
   <cd>
      <title>heart</title>
      <artist>Bonnie</artist>
      <artist> Tyler</artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
   </cd>
   <cd>
      <title/>
      <artist>Dolly Parton</artist>
      <country>USA</country>
      <company>RCA</company>
      <price>9.90</price>
      <year>1982</year>
   </cd>
</catalog>
<catalog>
   <cd>
      <title>Burlesque</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Empire</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Emp</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Em</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Hide your</title>
      <artist>Bonnie</artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
   </cd>
   <cd>
      <title>heart</title>
      <artist> Tyler</artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
   </cd>
   <cd>
      <title/>
      <artist>Dolly Parton</artist>
      <country>USA</country>
      <company>RCA</company>
      <price>9.90</price>
      <year>1982</year>
   </cd>
</catalog>

滑稽
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
帝国
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
电磁脉冲
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
相对长度单位
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
隐藏你的
邦妮
英国
哥伦比亚唱片公司
9.90
1988
心
泰勒
英国
哥伦比亚唱片公司
9.90
1988
多莉·帕顿
美国
RCA
9.90
1982

一次请参见标签。它来了两次。隐藏你的Bonnie Tyler UK CBS Records 9.90 1988心脏Bonnie Tyler UK CBS Records 9.90 1988@ram.bi:我明白了,所以你想要的比简单的碎纸更复杂,不同的艺术家需要结合不同的标题。但是你必须编辑这个问题并解释哪个艺术家应该和哪个标题匹配。有可能两位艺术家都唱同一首歌(我假设),或者两位艺术家都唱这两首歌,或者第一位艺术家唱第二首歌(假设艺术家和歌曲按名称的字母顺序排列。请编辑问题并指定确切的规则。嗨,Dimitre,感谢您的回复。一旦我添加了解释,请将我置于正确的方向。@ram.bi:当然,请在回答的最后查看我的更新:)我正在SQL Server Integration Services XML任务中使用该XML和XSLT,当时我遇到了一个错误,如::找不到实现前缀“ext”的脚本或外部对象。我对XSLT不太了解。请帮助我?一次请查看标记。它将出现两次。隐藏您的Bonnie Tyler UK CBS记录9.90 1988heart Bonnie Tyler UK CBS Records 9.90 1988@ram.bi:我明白了,所以你想要的比简单的切碎更复杂,不同的艺术家需要结合不同的标题。但是你必须编辑问题并解释哪个艺术家应该与哪个标题匹配。两个艺术家可能唱同一首歌(我假设),或者两位艺术家都唱这两首歌,或者第一位艺术家唱第二首歌(想象艺术)