I need to find out if anything exists between two nodes. My XML looks like this:
我需要找出两个节点之间是否存在任何问题。我的XML看起来像这样:
<event value1="1" value2="2" value3="3" info="some info here">
Line 1.<lb/>
Line 2.<lb/><lb/>
Line 3.<lb/>
Line 4.<lb/>
</event>
My goal is to convert the <lb/>
nodes to <br/>
HTML tags using XSLT. There is one additional requirement to fulfill though. In case there is one <lb/>
directly following another <lb/>
I want to output only one <br/>
.
我的目标是使用XSLT将
节点转换为HTML标签。但是还有一个额外的要求。如果有一个
直接跟在另一个
之后,我想只输出一个。
My XSLT looks like this:
我的XSLT看起来像这样:
<xsl:template match="lb">
<xsl:if test="not(preceding-sibling::lb[1])">
<br/>
</xsl:if>
</xsl:template>
The problem with the XSLT above is that it works correctly for line 1 only as the text between both nodes is ignored.
上面的XSLT的问题在于它仅对第1行正常工作,因为忽略了两个节点之间的文本。
Maybe someone here can help.
也许有人可以提供帮助。
3 个解决方案
#1
3
Edit: Another, more efficient way is this:
编辑:另一种更有效的方法是:
<xsl:template match="lb">
<xsl:if test="following-sibling::node()[1][not(self::lb)]">
<br/>
</xsl:if>
</xsl:template>
Try this:
<xsl:template match="lb">
<xsl:if test="generate-id()=generate-id(preceding-sibling::text()[1]/following-sibling::lb[1])">
<br/>
</xsl:if>
</xsl:template>
Basically this checks if you are on the first <lb/>
the previous text sibling node, which also means that it will only add <br/>
after some text, but not if the <lb/>
are at the beginning of the parent tag.
基本上这会检查你是否在前一个文本兄弟节点的第一个
上,这也意味着它只会在一些文本之后添加
,但如果
位于父节点的开头则不会标签。
#2
3
You are looking for something along the lines of this:
您正在寻找以下内容:
<!-- per default, <lb> gets removed (empty template)... -->
<xsl:template match="lb" />
<!-- ...unless it is directly preceded by a non-blank text node -->
<xsl:template match="lb[
normalize-space(preceding-sibling::node()[1][self::text()]) != ''
]">
<br />
</xsl:template>
This handles any arbitrary number of <lb/>
nodes that may occur consecutively.
这可以处理可能连续发生的任意数量的
节点。
Behavior for <lb/>
nodes that follow an element (not a text node) must still be defined. Currently they would be deleted. If you want to keep them, write an appropriate template for them.
仍然必须定义跟随元素(不是文本节点)的
节点的行为。目前他们将被删除。如果您想保留它们,请为它们编写适当的模板。
#3
1
This transformation:
<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="lb"/>
<xsl:template match=
"lb[not(following-sibling::node()[1][self::lb])]">
<br />
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
当应用于提供的XML文档时:
<event value1="1" value2="2" value3="3" info="some info here">
Line 1.<lb/>
Line 2.<lb/><lb/>
Line 3.<lb/>
Line 4.<lb/>
</event>
produces the wanted result:
产生想要的结果:
<event value1="1" value2="2" value3="3" info="some info here">
Line 1.<br/>
Line 2.<br/>
Line 3.<br/>
Line 4.<br/>
</event>
Do note:
-
The use and overriding of the identity transform.
身份变换的使用和覆盖。
-
How
<lb>
elements are deleted by default.默认情况下如何删除
元素。
-
How only the last
<lb>
element in a group of adjacent sibling<lb>
nodes is processed in a more special way -- is replaced by a<br />
element.如何以更特殊的方式处理一组相邻兄弟
节点中的最后一个
元素 - 由
元素替换。
#1
3
Edit: Another, more efficient way is this:
编辑:另一种更有效的方法是:
<xsl:template match="lb">
<xsl:if test="following-sibling::node()[1][not(self::lb)]">
<br/>
</xsl:if>
</xsl:template>
Try this:
<xsl:template match="lb">
<xsl:if test="generate-id()=generate-id(preceding-sibling::text()[1]/following-sibling::lb[1])">
<br/>
</xsl:if>
</xsl:template>
Basically this checks if you are on the first <lb/>
the previous text sibling node, which also means that it will only add <br/>
after some text, but not if the <lb/>
are at the beginning of the parent tag.
基本上这会检查你是否在前一个文本兄弟节点的第一个
上,这也意味着它只会在一些文本之后添加
,但如果
位于父节点的开头则不会标签。
#2
3
You are looking for something along the lines of this:
您正在寻找以下内容:
<!-- per default, <lb> gets removed (empty template)... -->
<xsl:template match="lb" />
<!-- ...unless it is directly preceded by a non-blank text node -->
<xsl:template match="lb[
normalize-space(preceding-sibling::node()[1][self::text()]) != ''
]">
<br />
</xsl:template>
This handles any arbitrary number of <lb/>
nodes that may occur consecutively.
这可以处理可能连续发生的任意数量的
节点。
Behavior for <lb/>
nodes that follow an element (not a text node) must still be defined. Currently they would be deleted. If you want to keep them, write an appropriate template for them.
仍然必须定义跟随元素(不是文本节点)的
节点的行为。目前他们将被删除。如果您想保留它们,请为它们编写适当的模板。
#3
1
This transformation:
<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="lb"/>
<xsl:template match=
"lb[not(following-sibling::node()[1][self::lb])]">
<br />
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
当应用于提供的XML文档时:
<event value1="1" value2="2" value3="3" info="some info here">
Line 1.<lb/>
Line 2.<lb/><lb/>
Line 3.<lb/>
Line 4.<lb/>
</event>
produces the wanted result:
产生想要的结果:
<event value1="1" value2="2" value3="3" info="some info here">
Line 1.<br/>
Line 2.<br/>
Line 3.<br/>
Line 4.<br/>
</event>
Do note:
-
The use and overriding of the identity transform.
身份变换的使用和覆盖。
-
How
<lb>
elements are deleted by default.默认情况下如何删除
元素。
-
How only the last
<lb>
element in a group of adjacent sibling<lb>
nodes is processed in a more special way -- is replaced by a<br />
element.如何以更特殊的方式处理一组相邻兄弟
节点中的最后一个
元素 - 由
元素替换。