xslt - xslt 通过子字符串删除重复值
问题描述
我有以下类别:
<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>
这里的问题是类别路径是“重复的”。基本上我想删除所有父类别路径,只包括最具体的级别。所以结果应该是这样的:
<categories>
<category>anotherparent</category>
<category>parent/child1/subchild1</category>
<category>parent/child2</category>
<category>parent/child3/subchild3</category>
</categories>
我可以考虑一些 java 扩展,但我找不到正确的方法/函数如何在 xslt 中执行此操作,我很确定它应该很容易。
它可以是 xslt 2 或 3。
解决方案
也许
<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>
有帮助;假设,就像评论所要求的那样,尾随/
是<category>parent/child3/</category>
一个错字,并且是<category>parent/child3</category>
. 如果parent/child3/
可以发生但应该被视为parent/child3
then 使用tokenize(., '/')[normalize-space()]
而不是tokenize(., '/')
.
在函数中使用包含两个项目的映射序列而不是大小为 2 的数组序列可能更简洁:
<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>
同样,如果可能出现尾随或前导或在斜杠之间,可能需要使用tokenize(., '/')[normalize-space()]
而不是,tokenize(., '/')
但应该忽略。
推荐阅读
- sql - 如果日期超过 24 小时,周末除外
- javascript - 在文档中搜索用户名或显示名
- google-apps-script - 谷歌表格脚本条件格式错误:数据中的行数与范围内的行数不匹配
- dafny - 需要在 a 中断言 a[0]
- python - 如何在 django 中重新安装 db.sqlite3 文件
- c++ - 当参数必须是使用指针的二维数组时如何在 C++ 中使用 swap()
- linux - 从在 Docker 上运行的 .ner core 3.1 连接 Db2
- python - Python/Jython 子进程模块的内存问题
- html - 在 Netlify.toml 文件中设置多个重定向
- r - 仅对缺失日期使用滞后函数递增日期