xslt通过子字符串消除重复数据
我有以下几类:xslt通过子字符串消除重复数据,xslt,Xslt,我有以下几类: <categories> <category>anotherparent</category> <category>parent</category> <category>parent/child1</category> <category>parent/child1/subchild1</category> <category
<categories>
<category>anotherparent</category>
<category>parent</category>
<category>parent/child1</category>
<category>parent/child1/subchild1</category>
<category>parent/child2</category>
<category>parent/child3/</category>
<category>parent/child3/subchild3</category>
</categories>
另一个父母
父母亲
父母/子女1
父母/子女1/子女1
父母/子女2
父母/子女3/
父母/子女3/子子女3
这里的问题是类别路径是“重复的”。基本上,我想删除所有父类别路径,只包括最具体的级别。
所以结果应该是这样的:
<categories>
<category>anotherparent</category>
<category>parent/child1/subchild1</category>
<category>parent/child2</category>
<category>parent/child3/subchild3</category>
</categories>
另一个父母
父母/子女1/子女1
父母/子女2
父母/子女3/子子女3
我可以考虑一些java扩展,但我找不到合适的方法/函数如何在xslt中实现这一点,我很确定这应该很容易
它可以是xslt 2或xslt 3。如果您输入的XML始终是您发布的格式,则可以:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="category[starts-with(following-sibling::category[1],.)]"/>
</xsl:stylesheet>
看到它在这里工作了吗:也许吧
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
expand-text="yes"
exclude-result-prefixes="#all"
xmlns:mf="http://example.com/mf"
version="3.0">
<xsl:function name="mf:group" as="element(category)*">
<xsl:param name="cats"/>
<xsl:param name="level"/>
<xsl:choose>
<xsl:when test="$cats?2[$level]">
<xsl:for-each-group select="$cats[?2[$level]]" group-by="?2[$level]">
<xsl:sequence select="mf:group(current-group(), $level + 1)"/>
</xsl:for-each-group>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="$cats?1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output indent="yes"/>
<xsl:template match="categories">
<xsl:copy>
<xsl:sequence select="mf:group(category ! [., tokenize(., '/')], 1)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
同样,如果可能出现尾随、前导或中间斜杠,但应忽略,则可能需要使用
tokenize(,“/”)[normalize-space()]
而不是tokenize(,“/”)
,我的数据略有不同,在模板中,如果更改类别的顺序,则它将不起作用。parent/child3/
中有一个尾随的/
。这是一个打字错误还是可以预期的?是的,第一个作品。我处理的数据非常奇怪,所以有时候末尾有一条斜线,有时候它不在那里。非常感谢。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
expand-text="yes"
exclude-result-prefixes="#all"
xmlns:mf="http://example.com/mf"
version="3.0">
<xsl:function name="mf:group" as="element(category)*">
<xsl:param name="cats" as="map(xs:string, item()*)*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:choose>
<xsl:when test="$cats?tokens[$level]">
<xsl:for-each-group select="$cats[?tokens[$level]]" group-by="?tokens[$level]">
<xsl:sequence select="mf:group(current-group(), $level + 1)"/>
</xsl:for-each-group>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="$cats?cat"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output indent="yes"/>
<xsl:template match="categories">
<xsl:copy>
<xsl:sequence select="mf:group(category ! map { 'cat' : ., 'tokens' : tokenize(., '/') }, 1)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>