1

这是我的源 XML。它最初是一个 Word-ML,已简化为自己的结构。名称为“aaa”的元素可以有任何名称。问题是脚注的处理:

<root>
  <doc>
    <comment>text text text <footnote id="1" > text text text</comment>
    <aaa>text text text</aaa>
    <aaa>text text text<footnote id="2" /> text text text </aaa>
    <aaa>text text text<aaa/> text <footnote id="3" symbol="*"/></aaa>
    <aaa>text text text text</aaa>
    <aaa>text text text text<aaa>text text text<footnote id="4"  /></aaa></aaa>
 <aaa>text text text text<aaa>text text text<footnote id="4"  /></aaa></aaa>
 <aaa>text text text text<aaa>text text text<footnote id="5"  /></aaa></aaa>
    <aaa>text text text</aaa>
  </doc>
</root>

我必须将此 Source-XML 转换为另一个 XML。我要做的一件事是用对应的数字替换脚注。

但不能只使用 ID-Attribute。ID 只是一个内部号码。脚注应该是渐进的,并且有以下条件:

  • 条件 1:应忽略节点“comment”的子节点“脚注”。整个节点“评论”被忽略。
  • 条件 2:具有符号属性的“脚注”不计算在内(我必须显示符号而不是数字)
  • 条件3:有可能一些注释有相同的id(只有很小的百分比,但有时同一个脚注有更多的链接)。

输出应该是这样的(结构不一样,现在只对脚注的处理感兴趣):

<root>
  <doc>
    <aaa>text text text</aaa>
    <aaa>text text text[1] text text text </aaa>
    <aaa>text text text<aaa/> text [*]</aaa>
    <aaa>text text text text</aaa>
    <aaa>text text text text<aaa>text text text[2]</aaa></aaa>
 <aaa>text text text text<aaa>text text text[2]</aaa></aaa>
 <aaa>text text text text<aaa>text text text[3]</aaa></aaa>
    <aaa>text text text</aaa>
  </doc>
</root>

我的第一个想法是有一个全局计数器变量,我根据条件递增。但由于 XSLT 中的变量是不可变的,因此它并不是一个真正的选择。

我还尝试计算出现在当前脚注之前的先前脚注。

        <xsl:template match="footnote">
         <xsl:call-template name="getFootnoteNumber">
          <xsl:with-param name="footNodeId" select="@id"/>
         </xsl:call-template>
        </xsl:template>

    <!-- simple template which only counts the footnotes
    that occur before the current footnode 
    the conditions 1, 2 and 3 are not yet included -->
        <xsl:template name="getFootnoteNumber">
           <xsl:param name="footNodeId"/>
           <xsl:value-of select="count(//footnote[position()&lt;=$footNodeId])"></xsl:value-of>     
    </xsl:template>
    <!-- i mostly get value "0", 
    or other strange numbers: for footNodeID=45 i get value 75, 
    doesn't really work-->

是否有可能开发一个全球计数器?

还是我必须以另一种方式计算以前的脚注?虽然我真的不知道如何实现条件 3。

任何回答 cpt.oneeye 的问候和感谢

4

2 回答 2

2

这个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="foot" match="footnote[not(ancestor::comment)][not(@symbol)]" use="@id"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="footnote[ancestor::comment]" priority="1" />
    <xsl:template match="footnote[@symbol]">
        <xsl:value-of select="concat('[',@symbol,']')"/>
    </xsl:template>
    <xsl:template match="footnote">
        <xsl:value-of select="concat('[',count(key('foot',@id)[1]/preceding::footnote[generate-id(.)=generate-id(key('foot',@id)[1])])+1,']')"/>
    </xsl:template>
</xsl:stylesheet>

正确输入:

<root>
    <doc>
        <comment>text text text <footnote id="1" /> text text text</comment>
        <aaa>text text text</aaa>
        <aaa>text text text <footnote id="2" /> text text text</aaa>
        <aaa>text text text <aaa/>text <footnote id="3" symbol="*"/></aaa>
        <aaa>text text text text</aaa>
        <aaa>text text text text <aaa>text text text <footnote id="4"  /></aaa></aaa>
        <aaa>text text text text <aaa>text text text <footnote id="4"  /></aaa></aaa>
        <aaa>text text text text <aaa>text text text <footnote id="5"  /></aaa></aaa>
        <aaa>text text text</aaa>
    </doc>
</root>

结果:

<root>
    <doc>
        <comment>text text text  text text text</comment>
        <aaa>text text text</aaa>
        <aaa>text text text [1] text text text</aaa>
        <aaa>text text text <aaa></aaa>text [*]</aaa>
        <aaa>text text text text</aaa>
        <aaa>text text text text <aaa>text text text [2]</aaa></aaa>
        <aaa>text text text text <aaa>text text text [2]</aaa></aaa>
        <aaa>text text text text <aaa>text text text [3]</aaa></aaa>
        <aaa>text text text</aaa>
    </doc>
</root>

编辑:小姐braquets。接下来,我将发布一个没有前面轴的答案。

于 2010-07-13T15:44:13.780 回答
1

XSLT 2.0 解决方案:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes"/>

 <xsl:key name="kPosById" match="@pos" use="../@id"/>

 <xsl:variable name="vdistinctFootnotes">
  <xsl:for-each-group group-by="@id" select=
    "/*/*/*[not(self::comment)]//footnote[not(@symbol)]">

    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:attribute name="pos" select="position()"/>
    </xsl:copy>
  </xsl:for-each-group>
 </xsl:variable>

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

    <xsl:template match="footnote">
      <xsl:value-of select=
      "concat('[', key('kPosById', @id, $vdistinctFootnotes), ']')"/>
    </xsl:template>

    <xsl:template match="footnote[@symbol]">
     <xsl:value-of select="concat('[', @symbol, ']')"/>
    </xsl:template>

    <xsl:template match="footnote[ancestor::comment]"/>
</xsl:stylesheet>

当将此转换应用于提供的文档时(更正为格式正确):

<root>
  <doc>
    <comment>text text text <footnote id="1" /> text text text</comment>
    <aaa>text text text</aaa>
    <aaa>text text text<footnote id="2" /> text text text </aaa>
    <aaa>text text text<aaa/> text <footnote id="3" symbol="*"/></aaa>
    <aaa>text text text text</aaa>
    <aaa>text text text text<aaa>text text text<footnote id="4"  /></aaa></aaa>
 <aaa>text text text text<aaa>text text text<footnote id="4"  /></aaa></aaa>
 <aaa>text text text text<aaa>text text text<footnote id="5"  /></aaa></aaa>
    <aaa>text text text</aaa>
  </doc>
</root>

产生了想要的结果

<root>
  <doc>
    <comment>text text text  text text text</comment>
    <aaa>text text text</aaa>
    <aaa>text text text[1] text text text </aaa>
    <aaa>text text text<aaa/> text [*]</aaa>
    <aaa>text text text text</aaa>
    <aaa>text text text text<aaa>text text text[2]</aaa></aaa>
 <aaa>text text text text<aaa>text text text[2]</aaa></aaa>
 <aaa>text text text text<aaa>text text text[3]</aaa></aaa>
    <aaa>text text text</aaa>
  </doc>
</root>
于 2010-07-13T16:37:50.530 回答