我有一堆文件,我正试图用xslt设置样式,我有一些像这样的代码:
<tag1>Something</tag1>
<tag2>Something else</tag2>
<tag3>...</tag3>
但在某些文件中可能只有:
<tag2>Something else</tag2>
<tag3>...</tag3>
当我渲染文档时,我想在tag1,tag2或tag3之前添加一个“<h2>Heading</h2>
”(它首先出现)。这可能吗?
答案 0 :(得分:2)
就这么简单(没有条件指令,没有xsl:element
,没有starts-with()
,没有preceding-sibling::
轴,没有模式,只有一个模板覆盖标准身份规则): 强>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[self::tag1 or self::tag2 or self::tag3][1]">
<h2>Heading</h2>
<xsl:call-template name="identity"/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于以下XML文档(将提供的片段包装到单个顶部元素中,以构成格式良好的XML文档):
<t>
<tag1>Something</tag1>
<tag2>Something else</tag2>
<tag3>...</tag3>
</t>
产生了想要的正确结果:
<t>
<h2>Heading</h2>
<tag1>Something</tag1>
<tag2>Something else</tag2>
<tag3>...</tag3>
</t>
请注意:
如果有许多元素名称(不一定以相同的字符串开头,那么重新写入最后一个模板的匹配模式会更短,更实用,如下所示:
<xsl:template match=
"*[contains('|tag1|tag2|tag3|', concat('|',name(),'|'))][1]">
答案 1 :(得分:1)
<xsl:if test="count(./preceding-sibling::*)=0"><h2>Heading</h2></xsl:if>
这意味着当前节点在文档中前面有0个兄弟元素(即,是其父元素的第一个元素)。但是如评论:定位父元素并将H2添加到其输出将产生更好的性能。
总是有一个包含标记,在最坏的情况下,它是文档元素本身。
答案 2 :(得分:0)
略有不同的方法:
<xsl:template match="*[tag1|tag2|tag3]">
<xsl:element name="{name()}">
<h2>Heading</h2>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="tag1|tag2|tag3">
<xsl:element name="{name()}"><xsl:apply-templates/></xsl:element>
</xsl:template>
答案 3 :(得分:0)
这是我发现的对我有用的东西:
<xsl:template match="*[starts-with(name(), 'tag')][1]" priority="1">
<h2>Heading</h2>
<xsl:apply-templates select="." mode="display"/>
</xsl:template>
<xsl:template match="*[starts-with(name(), 'tag')]">
<xsl:apply-templates select="." mode="display"/>
</xsl:template>
<xsl:template match="root/tag1" mode="display">
<p>First tag:
<xsl:apply-templates />
</p>
</xsl:template>
<xsl:template match="root/tag2" mode="display">
<p>Second tag:
<xsl:apply-templates />
</p>
</xsl:template>
<xsl:template match="root/tag3" mode="display">
<p>Third tag:
<xsl:apply-templates />
</p>
</xsl:template>
有点不正统,但它运作正常。
答案 4 :(得分:0)
此XSLT 1.0样式表......
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="@*|node()" name="ident">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="*[self::tag1|self::tag2|self::tag3]
[not(preceding-sibling::tag1|
preceding-sibling::tag2|
preceding-sibling::tag3)]">
<h2>Heading</h2>
<xsl:call-template name="ident" />
</xsl:template>
</xsl:stylesheet>
...或者等效于此XSLT 2.0 ...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="*[self::tag1|self::tag2|self::tag3]
[not(preceding-sibling::tag1|
preceding-sibling::tag2|
preceding-sibling::tag3)]">
<h2>Heading</h2>
<xsl:next-match />
</xsl:template>
</xsl:stylesheet>
...将转换此输入文档..
<t>
<branch1>
<something-before/>
<tag1>Something</tag1>
<tag2>Something else</tag2>
<tag3>tag3 content</tag3>
<something-after/>
</branch1>
<branch2>
<something-before/>
<tag3>tag3 content</tag3>
<tag2>Something else</tag2>
<something-after/>
</branch2>
</t>
<强> ...到... 强>
<t>
<branch1>
<something-before />
<h2>Heading</h2>
<tag1>Something</tag1>
<tag2>Something else</tag2>
<tag3>tag3 content</tag3>
<something-after />
</branch1>
<branch2>
<something-before />
<h2>Heading</h2>
<tag3>tag3 content</tag3>
<tag2>Something else</tag2>
<something-after />
</branch2>
</t>