2

我知道这与原始问题不同,但这是我为达到以下预期结果而考虑的一个思考过程:

XML 输入:

<section hangIndent="no" indent="arabic 1 digit"
isProposedAmendment="no" label="2A">
<title>AAA</title>
<body>
 BBB<subSection label="1">
  <body>
    <para hangIndent="yes" indent="loweralpha 1 character"
     isProposedAmendment="no" label="a">
      <body>
        CCC
      </body>
    </para>
    <para hangIndent="yes" indent="loweralpha 1 character"
      isProposedAmendment="no" label="b">
      <body>
        DDD
      </body>
    </para>
    <para hangIndent="yes" indent="loweralpha 1 character"
     isProposedAmendment="no" label="c">
      <body>
        EEE
      </body>
    </para>
  </body>
</subSection>
</body>
<annotation isProposedAmendment="no">
FFFFF
</annotation>
</section>

所需的输出:我根据每个节点的标签构建一个 xmlpath 名称,并将其插入每个端点。

<nm:xmlpath name ="2A" />
<section hangIndent="no" indent="arabic 1 digit"
isProposedAmendment="no" label="2A">
<title>AAA</title>
<body>
 BBB
<nm:xmlpath name ="2A 1" /> 
<subSection label="1">
  <body>
    <nm:xmlpath name ="2A 1(a)" />
    <para hangIndent="yes" indent="loweralpha 1 character"
isProposedAmendment="no" label="a">
      <body>
        CCC
      </body>
    </para>
    <nm:xmlpath name ="2A 1(b)" />
    <para hangIndent="yes" indent="loweralpha 1 character"
  isProposedAmendment="no" label="b">
      <body>
        DDD
      </body>
    </para>
    <nm:xmlpath name ="2A 1(c)" />
    <para hangIndent="yes" indent="loweralpha 1 character"
  isProposedAmendment="no" label="c">
      <body>
        EEE
      </body>
    </para>
  </body>
</subSection>
</body>
<annotation isProposedAmendment="no">
FFFFF
</annotation>
</section>
4

2 回答 2

0

基本方法是使用一个模板来匹配具有label属性的任何元素,并在该元素之前插入一个由您在父母、祖父母等身上找到nm:xmlpath的所有属性构成的模板。label

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

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

  <xsl:template match="*[@label]">
    <nm:xmlpath>
      <xsl:attribute name="name">
        <xsl:apply-templates select="." mode="xmlpath" />
      </xsl:attribute>
    </nm:xmlpath>
    <xsl:call-template name="identity" />
  </xsl:template>

  <!-- templates to construct the xmlpath, these should produce text nodes -->

  <!-- general case - path is the enclosing path (if any), followed by space,
       followed by our own @label -->
  <xsl:template match="*" mode="xmlpath">
    <xsl:if test="ancestor::*[@label]">
      <xsl:apply-templates select="ancestor::*[@label][1]" mode="xmlpath" />
      <xsl:text> </xsl:text>
    </xsl:if>
    <xsl:value-of select="@label" />
  </xsl:template>

  <!-- special case for para - no space after enclosing path, and surround
       our label with () -->
  <xsl:template match="para" mode="xmlpath">
    <xsl:apply-templates select="ancestor::*[@label][1]" mode="xmlpath" />
    <xsl:value-of select="concat('(', @label, ')')" />
  </xsl:template>

</xsl:stylesheet>

为了生成格式良好的 XML,输入文档的根元素不能label属性——如果有,我们会尝试nm:xmlpath在它之前插入一个属性,为输出文档提供两个根级元素。

于 2013-03-15T12:49:06.170 回答
0
<xsl:template match="/">
  <xsl:apply-templates select="//*"/>
</xsl:template>

<xsl:template match="*">
  <xsl:copy>
    <xsl:value-of select="text()[1]"/>
  </xsl:copy>
</xsl:template>

应该足够了。

于 2013-03-15T12:03:28.163 回答