我必须为两个节点之间存在的节点应用模板
实施例..
<w:p w:rsidR="00EF034A" w:rsidRDefault="00360D3B">
<w:commentRangeStart w:id="0"/>
<w:r>
<w:t>Comments</w:t>
</w:r>
<w:commentRangeEnd w:id="0"/>
<w:r>
<w:rPr>
<w:rStyle w:val="CommentReference"/>
</w:rPr>
<w:commentReference w:id="0"/>
</w:r>
</w:p>
我必须为commentRangeStart
和commentRangeEnd
之间的节点应用模板。请帮我写xslt模板。提前致谢
答案 0 :(得分:3)
看起来你正在处理并行/重叠标记,其中“commentrangestart”和“commentrangeend”元素充当“里程碑”标记。有关于处理重叠标记的大量文献,花一些时间研究这个主题是值得的。
细节取决于父元素中是否只有一个注释范围,范围是否始终在同一元素中开始和结束,等等。
在XSLT 2.0中,您通常可以使用<xsl:for-each-group group-starting-with="commentrangestart">
或<xsl:for-each-group group-ending-with="commentrangeend">
来处理此类构造。你也可以使用&lt;&lt;和&gt;&gt;运算符,例如<xsl:for-each select="*[. >> $start and . << $end]">
。
如果你坚持使用XSLT 1.0,那将会困难得多,但并非不可能。使用的技术(值得学习,因为它对XSLT 2.0也很有用)称为“兄弟递归”。您编写了一个与commentrangestart元素匹配的模板并执行<xsl:apply-templates mode="sibling" select="following-sibling::*[1]"/>
;你在mode =“sibling”中有两个模板规则,一个匹配commentrangeend元素并终止递归,另一个处理两者之间的元素,并通过递归调用结束<xsl:apply-templates mode="sibling" select="following-sibling::*[1]"/>
答案 1 :(得分:3)
这是一个简单的XPath 1.0(XSLT 1.0)解决方案,除了凯博士的完整答案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w="w:w">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select=
"*/w:p/w:commentRangeStart[@w:id=0]
/following-sibling::node()
[following-sibling::w:commentRangeEnd[@w:id=0] ]
"/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档(包装到顶部元素中,格式正确):
<t xmlns:w="w:w">
<w:p w:rsidR="00EF034A" w:rsidRDefault="00360D3B">
<w:commentRangeStart w:id="0"/>
<w:r>
<w:t>Comments</w:t>
</w:r>
<w:commentRangeEnd w:id="0"/>
<w:r>
<w:rPr>
<w:rStyle w:val="CommentReference"/>
</w:rPr>
<w:commentReference w:id="0"/>
</w:r>
</w:p>
</t>
生成了所需的正确结果(将标识模板应用于所选节点):
<w:r xmlns:w="w:w">
<w:t>Comments</w:t>
</w:r>