在XSL 1.0中,我试图区分以下两种情况,这两种情况都发生在我需要处理的输入XML中,并且每种情况都要以不同方式处理。
情景1
<tag1><tag2/> some text</tag1>
情景2
<tag1>some text <tag2/></tag1>
我有一个匹配<tag2/>
级别的模板,在此我想要的方案1中忽略<tag2/>
,在方案2中我想插入<br/>
代替{{ 1}}。
我在这里和谷歌搜索过,但似乎无法根据<tag2/>
中<tag2/>
的位置找出如何区分。
我调查了前兄弟和 generate-id ,并试图使用类似的内容: -
<tag1>
和
not(
generate-id(
preceding-sibling::node()[1]
)
= generate-id(
preceding-sibling::text()[1]
)
)
position()
的似乎没有帮助,因为两者似乎都在节点级别运行?
欢迎任何想法?
由于 罗杰
答案 0 :(得分:1)
查看这些模式:
node()[1]
匹配第一个节点子节点。
node()[1][self::tag2]
此匹配第一个节点子节点,也是tag2
元素。
node()[not(self::text()[not(normalize-space())])][1][self::tag2]
匹配第一个节点子节点,它不是仅空白文本节点,也是tag2
元素(如果您使用XHTML输入保留空白,则只保留文本节点)。
我给你这种方法,因为第一和第二个模式是streamable(preceding
轴不可流动)。
注意:第二个必须重写为node()[position() = 1 and self::tag2]
。
答案 1 :(得分:0)
以下样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="tag2[preceding-sibling::text()]">
<br/>
</xsl:template>
</xsl:stylesheet>
在此输入上:
<items>
<tag1><tag2/>some text</tag1>
<tag1>some text <tag2/></tag1>
</items>
产地:
some text
some text <br/>
更复杂的解决方案需要有关所需输出的其他信息。
答案 2 :(得分:0)
更简单,更基本的解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"node()[self::tag2 and position()=1]"/>
<xsl:template match=
"node()[self::tag2 and position()=2]">
<br/>
</xsl:template>
</xsl:stylesheet>
应用于此XML文档:
<tag1><tag2/> some text</tag1>
会产生想要的正确结果:
<tag1> some text</tag1>
应用于此文档时:
<tag1>some text <tag2/></tag1>
再次生成想要的正确答案:
<tag1>some text <br/>
</tag1>
<强>解释强>:
标识规则(模板)按原样复制每个节点。
覆盖标识规则的第一个模板匹配名称为tag2
且节点列表中的位置为1的任何节点。它没有正文,因此tag2
元素是忽略。
覆盖标识规则的第二个模板与第一个类似,但匹配的tag2
节点的位置必须为2.在这种情况下,它将替换为<br/>
。