使用XSLT 1.0在不同级别存在同名键时进行分组
我有以下输入xml:使用XSLT 1.0在不同级别存在同名键时进行分组,xslt,xslt-1.0,Xslt,Xslt 1.0,我有以下输入xml: <?xml version="1.0" encoding="UTF-8"?> <root> <results> <case> <KEY>c1</KEY> <issue> <KEY>i1</KEY> <id>Apple</id>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<results>
<case>
<KEY>c1</KEY>
<issue>
<KEY>i1</KEY>
<id>Apple</id>
</issue>
<issue>
<KEY>i1</KEY>
<id>Orange</id>
</issue>
<issue>
<KEY>i2</KEY>
<id>Mango</id>
</issue>
</case>
<case>
<KEY>c1</KEY>
<issue>
<KEY>i5</KEY>
<id>Apricot</id>
</issue>
<issue>
<KEY>i5</KEY>
<id>Blueberry</id>
</issue>
<issue>
<KEY>i6</KEY>
<id>blackberry</id>
</issue>
</case>
<case>
<KEY>c2</KEY>
<issue>
<KEY>i3</KEY>
<id>Banana</id>
</issue>
<issue>
<KEY>i3</KEY>
<id>Cherry</id>
</issue>
<issue>
<KEY>i4</KEY>
<id>Grapes</id>
</issue>
</case>
</results>
</root>
c1
i1
苹果
i1
橙色
i2
芒果
c1
i5
杏
i5
蓝莓
i6
黑莓
c2
i3
香蕉
i3
樱桃
i4
葡萄
现在我想先按
的
进行分组,然后按
的
进行分组。我们的想法是按照问题密钥和案例密钥对所有
进行分组。最后,我想在
中的
节点下移动所有发行密钥相同的
我的输出xml应如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<results>
<case>
<KEY>c1</KEY>
<issue>
<KEY>i1</KEY>
<sources>
<sourceInstance>
<id>Apple</id>
</sourceInstance>
<sourceInstance>
<id>Orange</id>
</sourceInstance>
</sources>
</issue>
<issue>
<KEY>i2</KEY>
<sources>
<sourceInstance>
<id>Mango</id>
</sourceInstance>
</sources>
</issue>
<issue>
<KEY>i5</KEY>
<sources>
<sourceInstance>
<id>Apricot</id>
</sourceInstance>
<sourceInstance>
<id>Blueberry</id>
</sourceInstance>
</sources>
</issue>
<issue>
<KEY>i6</KEY>
<sources>
<sourceInstance>
<id>Apple</id>
</sourceInstance>
<sourceInstance>
<id>Orange</id>
</sourceInstance>
</sources>
</issue>
</case>
<case>
<KEY>c2</KEY>
<issue>
<KEY>i3</KEY>
<sources>
<sourceInstance>
<id>Banana</id>
</sourceInstance>
<sourceInstance>
<id>Cherry</id>
</sourceInstance>
</sources>
</issue>
<issue>
<KEY>i4</KEY>
<sources>
<sourceInstance>
<id>Grapes</id>
</sourceInstance>
</sources>
</issue>
</case>
</results>
</root>
c1
i1
苹果
橙色
i2
芒果
i5
杏
蓝莓
i6
苹果
橙色
c2
i3
香蕉
樱桃
i4
葡萄
我尝试使用以下XSLT,但无法获得所需的xml输出
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="case" match="case" use="string(KEY)" />
<xsl:key name="issue" match="case" use="concat(KEY, '|', KEY)" />
<xsl:template match="results">
<xsl:copy>
<xsl:apply-templates select="case[generate-id() = generate-id(key('case', string(KEY))[1])]" mode="case" />
</xsl:copy>
</xsl:template>
<xsl:template match="case" mode="case">
<xsl:choose>
<xsl:when test="KEY">
<case>
<xsl:copy-of select="KEY" />
<xsl:apply-templates select="key('case', KEY)[generate-id() = generate-id(key('issue', concat(KEY, '|', KEY))[1])]" mode="issue" />
</case>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="case " mode="issue">
<xsl:choose>
<xsl:when test="KEY">
<issue>
<xsl:copy-of select="KEY" />
<sources>
<xsl:apply-templates select="key('issue', id)" />
</sources>
</issue>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="case">
<sourceInstance>
<id>
<xsl:value-of select="id" />
</id>
</sourceInstance>
</xsl:template>
</xsl:stylesheet>
似乎我无法使用
的
和
框定键的正确组合,因为在这两个位置都存在同名节点(即
)
有人能告诉我XSLT中缺少了什么吗?主要问题是如何定义问题的关键
<xsl:key name="issue" match="case" use="concat(KEY, '|', KEY)" />
然后,要为给定的案例
键获取分组的问题
元素,您可以这样做
<xsl:apply-templates select="key('case', KEY)/issue[generate-id() = generate-id(key('issue', concat(KEY, '|', ../KEY))[1])]" mode="issue" />
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="case" match="case" use="string(KEY)" />
<xsl:key name="issue" match="issue" use="concat(KEY, '|', ../KEY)" />
<xsl:template match="results">
<xsl:copy>
<xsl:apply-templates select="case[generate-id() = generate-id(key('case', string(KEY))[1])]" mode="case" />
</xsl:copy>
</xsl:template>
<xsl:template match="case" mode="case">
<xsl:choose>
<xsl:when test="KEY">
<case>
<xsl:copy-of select="KEY" />
<xsl:apply-templates select="key('case', KEY)/issue[generate-id() = generate-id(key('issue', concat(KEY, '|', ../KEY))[1])]" mode="issue" />
</case>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="issue" mode="issue">
<xsl:choose>
<xsl:when test="KEY">
<issue>
<xsl:copy-of select="KEY" />
<sources>
<xsl:apply-templates select="key('issue', concat(KEY, '|', ../KEY))" />
</sources>
</issue>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="issue">
<sourceInstance>
<id>
<xsl:value-of select="id" />
</id>
</sourceInstance>
</xsl:template>
</xsl:stylesheet>
主要问题是如何定义问题的关键
<xsl:key name="issue" match="case" use="concat(KEY, '|', KEY)" />
然后,要为给定的案例
键获取分组的问题
元素,您可以这样做
<xsl:apply-templates select="key('case', KEY)/issue[generate-id() = generate-id(key('issue', concat(KEY, '|', ../KEY))[1])]" mode="issue" />
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="case" match="case" use="string(KEY)" />
<xsl:key name="issue" match="issue" use="concat(KEY, '|', ../KEY)" />
<xsl:template match="results">
<xsl:copy>
<xsl:apply-templates select="case[generate-id() = generate-id(key('case', string(KEY))[1])]" mode="case" />
</xsl:copy>
</xsl:template>
<xsl:template match="case" mode="case">
<xsl:choose>
<xsl:when test="KEY">
<case>
<xsl:copy-of select="KEY" />
<xsl:apply-templates select="key('case', KEY)/issue[generate-id() = generate-id(key('issue', concat(KEY, '|', ../KEY))[1])]" mode="issue" />
</case>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="issue" mode="issue">
<xsl:choose>
<xsl:when test="KEY">
<issue>
<xsl:copy-of select="KEY" />
<sources>
<xsl:apply-templates select="key('issue', concat(KEY, '|', ../KEY))" />
</sources>
</issue>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="issue">
<sourceInstance>
<id>
<xsl:value-of select="id" />
</id>
</sourceInstance>
</xsl:template>
</xsl:stylesheet>
太好了+谢谢你的快速反应。太好了+感谢您的快速响应。