XSLT中的Gobal计数器还是替代解决方案?
这是我的源XML。它最初是一个单词ML,已经简化为自己的结构。名为“aaa”的元素可以有任何类型的名称。问题在于脚注的处理:XSLT中的Gobal计数器还是替代解决方案?,xslt,xslt-2.0,Xslt,Xslt 2.0,这是我的源XML。它最初是一个单词ML,已经简化为自己的结构。名为“aaa”的元素可以有任何类型的名称。问题在于脚注的处理: <root> <doc> <comment>text text text <footnote id="1" > text text text</comment> <aaa>text text text</aaa> <aaa>text text tex
<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>
文本文本文本文本文本文本文本
文本文本文本
文本文本文本文本文本文本文本
文本文本文本文本
文本文本文本文本
文本文本文本文本文本文本文本
文本文本文本文本文本文本文本
文本文本文本文本文本文本文本
文本文本文本
我必须将这个源XML转换成另一个XML。我要做的一件事是用相应的数字替换脚注
但不可能只使用ID属性。ID只是一个内部编号。脚注应是渐进式的,并且存在以下条件:
- 条件1:应忽略节点“注释”的子节点“脚注”。忽略整个节点“注释”
- 条件2:具有符号属性的“脚注”不计算在内(我必须显示符号,而不是数字)
- 条件3:某些注释可能具有相同的id(只有很低的百分比,但有时有更多指向同一脚注的链接)李>
文本文本文本
文本[1]文本文本
文本[*]
文本文本文本文本
文本文本[2]
文本文本[2]
文本文本[3]
文本文本文本
我的第一个想法是有一个全局计数器变量,我根据条件递增它。但由于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()<=$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此样式表:
<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>
文本文本文本文本文本文本文本
文本文本文本
文本[1]文本文本
文本[*]
文本文本文本文本
正文[2]
正文[2]
正文[3]
文本文本文本
编辑:布拉克斯小姐。接下来,我将发布一个答案,前面没有轴。XSLT2.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 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>
文本文本文本文本文本文本文本
文本文本文本
文本[1]文本文本
文本[*]
文本文本文本文本
文本文本[2]
文本文本[2]
文本文本[3]
文本文本文本
很好的解决方案,但是依靠前面的:轴可能会有点低效(O(N^2)):@Dimitre:是的!XSLT1.0没有p/3键
函数。但是,如何计算O(N^2)复杂度呢?这是对O(N/2*N+1)的一般解释(假设“查找前置项”作为算法复杂性单元?@Alejandro:在XSLT1.0中,可以使用键()
在多个文档上运行函数。有一个技巧可以做到这一点。@Alejandro:非常感谢您提供的解决方案。当我在原始xmlsource上使用xsl时,效果非常好。但是当我将代码添加到现有xsl中时,它只对一些FootNode有效。大多数情况下,我得到的是“1”作为输出。必须与xsl的另一部分发生冲突,我还没有弄清楚。@Dimitre:是的。可以对上下文中的任何文档使用键
(例如,为每个,使用更改上下文),但对于构建“同类第一”脚注
的文档,我必须使用节点集()
XSLT1.0中的扩展,我是一个顽固的标准XSLT1.0人。
<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>