1

我有这个 xml 文件:

<A>
<B>
    <elt>Add</elt>
    ...there are some element here
    <bId>2</bId>
</B>
<B>
    <elt>Add</elt>
    ...there are some element here
    <bId>2</bId>
</B>
<B>
    <elt>Add</elt>
    ...there are some element here
    <bId>2</bId>
</B>
<B>
    <elt>can</elt>
    ...there are some element here
    <bId>3</bId>
</B>
<B>
    <elt>can</elt>
    ...there are some element here
    <bId>3</bId>
</B>

我想检查每个bId元素的值。如果这个值与前面或后面的bId元素相同,那么我会将 bloc B的其他元素放在另一个 bloc中,但转换后将被拒绝的元素bId除外。为了让您理解我的问题,这是预期的输出:

<CA>
  <cplx>
    <spRule>
            <elt>Add</elt>
             ...
    </spRule>
    <spRule>
            <elt>Add</elt>
             ...
    </spRule>
    <spRule>
            <elt>Add</elt>
            ...
    </spRule>
  </cplx>
  <cplx>
    <spRule>
            <elt>can</elt>
            ...
    </spRule>
    <spRule>
            <elt>can</elt>
            ...
    </spRule>
  </cplx>
</CA>

即使当 xml 文件中的元素未按 bId的值排序时,我也希望获得相同的预期输出。我尝试使用这个 xsl 代码:

<xsl:for-each select="bId"
  <CA>
    <cplx>
    <xsl:choose>
      <xsl:when test="node()[preceding::bId]">
         <xsl:copy>
          <xsl:copy-of select="@*"/>
          <xsl:apply-templates/>
         </xsl:copy>
      </xsl:when>
    </cplx>
  </CA>
</xsl:for-each>

但它不会走路。有人可以帮我吗?谢谢

4

1 回答 1

2

假设您的第一个描述是将具有相同值的相邻元素分组bId是您想要的 XSLT 1.0 方式如下:

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

  <xsl:key name="k1"
    match="B[bId = preceding-sibling::B[1]/bId]"
    use="generate-id(preceding-sibling::B[not(bId = preceding-sibling::B[1]/bId)][1])"/>

  <xsl:template match="A">
    <CA>
      <xsl:apply-templates select="B[not(preceding-sibling::B[1]) or not(bId = preceding-sibling::B[1]/bId)]"/>
    </CA>
  </xsl:template>

  <xsl:template match="B">
    <cplx>
      <xsl:apply-templates select=". | key('k1', generate-id())" mode="sp"/>
    </cplx>
  </xsl:template>

  <xsl:template match="B" mode="sp">
    <spRule>
      <xsl:copy-of select="node()[not(self::bId)]"/>
    </spRule>
  </xsl:template>

</xsl:stylesheet>

如果您只是想对B具有相同bId值的所有元素进行分组,请使用

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

  <xsl:key name="k1"
    match="B"
    use="bId"/>

  <xsl:template match="A">
    <CA>
      <xsl:apply-templates select="B[generate-id() = generate-id(key('k1', bId)[1])]"/>
    </CA>
  </xsl:template>

  <xsl:template match="B">
    <cplx>
      <xsl:apply-templates select="key('k1', bId)" mode="sp"/>
    </cplx>
  </xsl:template>

  <xsl:template match="B" mode="sp">
    <spRule>
      <xsl:copy-of select="node()[not(self::bId)]"/>
    </spRule>
  </xsl:template>

</xsl:stylesheet>
于 2012-10-09T09:47:23.163 回答