我需要为xml编写XSLT,其中包含以下格式。
<books>
<book>
<a>name</a>
<a>name</a>
<b>name</b>
<b>name</b>
</book>
</books>
我需要在某些条件下消除重复的子节点。
ie ..如果前一个节点(元素)是<a>
而当前节点(元素)也是<a>
,那么应该删除一个节点。
以上输出,
`<a>name</a>`
`<b>name</b>`
请帮我这样做。
答案 0 :(得分:2)
在XSLT 2或3中,您可以轻松地将相邻的兄弟元素按其节点名称与for-each-group select="*" group-adjacent="node-name()"
分组,并简单地输出每个组中的第一个项目(等于上下文项.
):< / p>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="book">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="node-name()">
<xsl:copy-of select="."/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
据我所知,你想省略叶元素(没有子元素) 如果它有一个以前的兄弟,其中:
所以最直观的解决方案(我认为)是写一个空模板, 只匹配这些节点:
<xsl:template match="*[not(*)][preceding-sibling::*[1][not(*)]
[name() = current()/name()][text() = current()/text()]]"/>
匹配属性的简要说明:
*[not(*)]
- 每个没有子元素的元素(叶元素)。[
- 第二个谓词的开头。
preceding-sibling::*[1]
- 采取前面的第一个兄弟姐妹。[not(*)]
- 不得有任何子元素。[name() = current()/name()]
- 它的名称必须与
“开始”元素。[text() = current()/text()]
- 必须与文字相同
“开始”元素。 ]
- 第二个谓词的结尾。当然,脚本还必须包含身份模板。
对于具有位扩展源的工作示例,请参阅http://xsltransform.net/jxN8Nqm
如果不需要相同文本的要求,请删除相应的文本 谓词片段。