XSLT复制相同的兄弟姐妹,直到出现其他兄弟姐妹

时间:2016-08-05 13:54:43

标签: xml xslt

平,

我正在尝试使用XSLT 1.0转换以下列表:

<div data-class="a"/>
<div data-class="b"/>
<div data-class="b"/>
<div data-class="c"/>
<div data-class="b"/>
<div data-class="a"/>
<div data-class="b"/>
<div data-class="c"/>
<div data-class="d"/>
<div data-class="a"/>
<div data-class="a"/>

它应该如下转换数据:

<div data-class="a">
    <div data-class="b"/>
    <div data-class="b">
        <div data-class="c"/>
    </div>
    <div data-class="b"/>
</div>
<div data-class="a">
    <div data-class="b">
        <div data-class="c">
            <div data-class="d"/>
        </div>
    </div>
</div>
<div data-class="a"/>
<div data-class="a"/>
    <div data-class="b">
        <div data-class="c"/>
        <div data-class="c"/>
    </div>
</div>

我正在努力从小时开始正确地改造它。 要转换它,我使用的是复制标记:

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

<xsl:template match="div[@data-class='a']">
  <xsl:copy>
    <xsl:apply-templates select="node() | @* | following-sibling::div[@data-class='b']" />
  </xsl:copy>
</xsl:template>

<xsl:template match="div[@data-class='a']">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()" />
    <xsl:apply-templates select="following-sibling::div[@data-class='b']" />
  </xsl:copy>
</xsl:template>

<xsl:template match="div[@dataclass='b']">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()" />
    <xsl:apply-templates select="following-sibling::div[@data-class='c']" />
  </xsl:copy>
</xsl:template>

问题是数据类的所有后续元素都被采用 - 请帮助我。 非常感谢!

1 个答案:

答案 0 :(得分:3)

我建议你这样试试:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="b" match="div[@data-class='b']" use="generate-id(preceding-sibling::div[@data-class='a'][1])" />
<xsl:key name="c" match="div[@data-class='c']" use="generate-id(preceding-sibling::div[@data-class='b'][1])" />
<xsl:key name="d" match="div[@data-class='d']" use="generate-id(preceding-sibling::div[@data-class='c'][1])" />

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

<xsl:template match="/root">
    <xsl:copy>
        <xsl:apply-templates select="div[@data-class='a']"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="div[@data-class='a']">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
        <xsl:apply-templates select="key('b', generate-id())"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="div[@data-class='b']">
    <xsl:copy>
    <xsl:apply-templates select="@*|node()" />
    <xsl:apply-templates select="key('c', generate-id())"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="div[@data-class='c']">
    <xsl:copy>
    <xsl:apply-templates select="@*|node()" />
    <xsl:apply-templates select="key('d', generate-id())"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

如果将以上内容应用于以下格式正确的输入示例:

<强> XML

<root>
    <div data-class="a"/>
    <div data-class="b"/>
    <div data-class="b"/>
    <div data-class="c"/>
    <div data-class="b"/>
    <div data-class="a"/>
    <div data-class="b"/>
    <div data-class="c"/>
    <div data-class="d"/>
    <div data-class="a"/>
    <div data-class="a"/>
</root>

结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <div data-class="a">
      <div data-class="b"/>
      <div data-class="b">
         <div data-class="c"/>
      </div>
      <div data-class="b"/>
   </div>
   <div data-class="a">
      <div data-class="b">
         <div data-class="c">
            <div data-class="d"/>
         </div>
      </div>
   </div>
   <div data-class="a"/>
   <div data-class="a"/>
</root>