这是xml:
的片段<sample>
<test>
<Cell1>John</Cell1>
<Cell2>A</Cell2>
<Cell4>xy</Cell4>
</test>
<test>
<Cell1>Jack</Cell1>
<Cell2>B</Cell2>
<Cell3>Red</Cell3>
<Cell6>10</Cell6>
</test>
<test>
<Cell1>John,Jade</Cell1>
<Cell2>A,Y</Cell2>
<Cell4>1</Cell4>
</test>
<test>
<Cell1>John,Jade</Cell1>
<Cell2>A B,X</Cell2>
<Cell3>Blue</Cell3>
</test>
</sample>
如果Cell2
包含逗号,则拆分值并检查前面的Cell2
是否包含相同的值,同样如果Cell2
包含空格,则拆分值并检查前面的{{1} }包含相同的值 - &gt;如果是这样,请忽略它。
这就是我想要输出的方式:
Cell2
这是我写的xslt :(请查看评论)
<Cell2>A</Cell2>
<Cell2>B</Cell2>
<Cell2>Y</Cell2>
<Cell2>X</Cell2>
我如何实现输出?任何想法??
答案 0 :(得分:5)
这个简单的转型:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:for-each select="distinct-values(/*/test/Cell2/tokenize(.,'[ ,]'))">
<Cell2><xsl:value-of select="."/></Cell2>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<sample>
<test>
<Cell1>John</Cell1>
<Cell2>A</Cell2>
<Cell4>xy</Cell4>
</test>
<test>
<Cell1>Jack</Cell1>
<Cell2>B</Cell2>
<Cell3>Red</Cell3>
<Cell6>10</Cell6>
</test>
<test>
<Cell1>John,Jade</Cell1>
<Cell2>A,Y</Cell2>
<Cell4>1</Cell4>
</test>
<test>
<Cell1>John,Jade</Cell1>
<Cell2>A B,X</Cell2>
<Cell3>Blue</Cell3>
</test>
</sample>
会产生想要的正确结果:
<Cell2>A</Cell2>
<Cell2>B</Cell2>
<Cell2>Y</Cell2>
<Cell2>X</Cell2>
<强>解释强>:
select
xsl:for-each
属性中的XPath表达式是理解的关键:
distinct-values(/*/test/Cell2/tokenize(.,'[ ,]'))
这将生成所有标记化(字符串值)/*/test/Cell2
答案 1 :(得分:3)
首先,如果您使用逗号或空格进行标记,则可以将您的标记化合并为一个表达式
<xsl:for-each select="tokenize(., ',|\s')">
你能做什么,首先匹配所有 Cell2 元素,你的模板标记内容,但把结果放在一个变量
<xsl:variable name="cells">
<xsl:apply-templates select="test/Cell2"/>
</xsl:variable>
然后你可以简单地使用 xsl:for-each-group 来迭代它们
<xsl:for-each-group select="$cells/Cell2" group-by="text()">
<xsl:copy-of select="."/>
</xsl:for-each-group>
这是完整的XSLT
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="sample">
<xsl:variable name="cells">
<xsl:apply-templates select="test/Cell2"/>
</xsl:variable>
<xsl:for-each-group select="$cells/Cell2" group-by="text()">
<xsl:copy-of select="."/>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="Cell2">
<xsl:for-each select="tokenize(., ',|\s')">
<Cell2>
<xsl:value-of select="."/>
</Cell2>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
当应用于您的示例XML时,输出以下内容
<Cell2>A</Cell2>
<Cell2>B</Cell2>
<Cell2>Y</Cell2>
<Cell2>X</Cell2>
答案 2 :(得分:1)
当您深度嵌套xsl:for-each指令时,上下文项会在每个级别更改,因此您经常需要将变量绑定到每个级别的上下文项,以便您可以返回它。但是,深度嵌套的xsl:for-each指令有时表明您应该将代码分解为更小的模板或函数。