Mor*_*075 7 xslt grouping distinct
我想在多个级别上从我的xml中获取不同的节点.任何人都可以给我一些提示如何做到这一点?我用Google搜索的方法(Muenchian方法,for-each-groups)用单个分组键和普通层次结构解释.
这是我的xml的一个例子:
<persons>
<person>
<name>Tom</name>
<age>20</age>
<mails>
<mail>x@test.com</mail>
<mail>y@test.com</mail>
</mails>
</person>
<person>
<name>Tom</name>
<age>20</age>
<mails>
<mail>y@test.com</mail>
<mail>z@test.com</mail>
</mails>
</person>
</persons>
Run Code Online (Sandbox Code Playgroud)
我想根据名称和年龄有不同的人员节点,还有一组不同的邮件节点.因此,对于该示例,期望的输出将是:
<persons>
<person>
<name>Tom</name>
<age>20</age>
<mails>
<mail>x@test.com</mail>
<mail>y@test.com</mail>
<mail>z@test.com</mail>
</mails>
</person>
</persons>
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点?非常感谢提前.
Dim*_*hev 11
I. XSLT 1.0解决方案:
这种转变:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kPersByNameAndAge" match="person"
use="concat(name, '+', age)"/>
<xsl:key name="kmailByNameAndAge" match="mail"
use="concat(../../name, '+', ../../age)"/>
<xsl:key name="kmailByNameAndAgeAndVal" match="mail"
use="concat(../../name, '+', ../../age, '+', .)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<persons>
<xsl:apply-templates select=
"person[generate-id()
=
generate-id(key('kPersByNameAndAge',
concat(name, '+', age)
)
[1]
)
]
"/>
</persons>
</xsl:template>
<xsl:template match="mails">
<mails>
<xsl:apply-templates select=
"key('kmailByNameAndAge', concat(../name, '+', ../age))
[generate-id()
=
generate-id(key('kmailByNameAndAgeAndVal',
concat(../../name, '+', ../../age, '+', .)
)
[1]
)
]
"/>
</mails>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当应用于提供的XML文档时:
<persons>
<person>
<name>Tom</name>
<age>20</age>
<mails>
<mail>x@test.com</mail>
<mail>y@test.com</mail>
</mails>
</person>
<person>
<name>Tom</name>
<age>20</age>
<mails>
<mail>y@test.com</mail>
<mail>z@test.com</mail>
</mails>
</person>
</persons>
Run Code Online (Sandbox Code Playgroud)
产生想要的,正确的结果:
<persons>
<person>
<name>Tom</name>
<age>20</age>
<mails>
<mail>x@test.com</mail>
<mail>y@test.com</mail>
<mail>z@test.com</mail>
</mails>
</person>
</persons>
Run Code Online (Sandbox Code Playgroud)
II.XSLT 2.0解决方案
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kmailByNameAndAge" match="mail"
use="concat(../../name, '+', ../../age)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<persons>
<xsl:for-each-group select="person" group-by="concat(name, '+', age)">
<xsl:apply-templates select="."/>
</xsl:for-each-group>
</persons>
</xsl:template>
<xsl:template match="mails">
<mails>
<xsl:for-each-group select=
"key('kmailByNameAndAge', concat(../name, '+', ../age))"
group-by="concat(../../name, '+', ../../age, '+', .)"
>
<xsl:apply-templates select="."/>
</xsl:for-each-group>
</mails>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8372 次 |
| 最近记录: |