我对XSL很新,需要一些帮助。我有一个XML文件需要转换如下: exisitng文件:
<root>
<highernode>
<highernodename>Name1</highernodename>
<highernodeId>Id1</highernodeId>
<node name="node1">
<somechild child-id="1"/>
</node>
<node name="node2">
<somechild child-id="2"/>
</node>
<node name="node3">
<somechild child-id="1"/>
</node>
<node name="node4">
<somechild child-id="2"/>
</node>
<node name="node5">
<somechild child-id="3"/>
</node>
</highernode>
<highernode>
<highernodename>Name2</highernodename>
<highernodeId>Id2</highernodeId>
<node name="node1">
<somechild child-id="1"/>
</node>
<node name="node2">
<somechild child-id="5"/>
</node>
<node name="node3">
<somechild child-id="5"/>
</node>
<node name="node6">
<somechild child-id="4"/>
</node>
<node name="node5">
<somechild child-id="3"/>
</node>
</highernode>
</root>
必须成为这样的东西:
<root>
<highernode>
<highernodename>Name1</highernodename>
<highernodeId>Id1</highernodeId>
<somechild>1
<node>node1</node>
<node>node3</node>
</somechild>
<somechild>2
<node>node2</node>
<node>node4</node>
</somechild>
<somechild>3
<node>node5</node>
</somechild>
</highernode>
<highernode>
<highernodename>Name2</highernodename>
<highernodeId>Id2</highernodeId>
<somechild>1
<node>node1</node>
</somechild>
<somechild>5
<node>node2</node>
<node>node3</node>
</somechild>
<somechild>4
<node>node6</node>
</somechild>
<somechild>3
<node>node5</node>
</somechild>
</highernode>
</root>
换句话说,在每个高节点中,我必须将属性somechild切换到节点,保持顺序,然后检查是否有几个具有相同值的子节点,并且在这种情况下,将它们的前节点分组同一个孩子。 在阅读了这个主题之后:Grouping XML nodes by attribute value in XSLT 它有所帮助,但是,经过一段时间的调整以满足自己的需求,我遇到了一些问题。我的XSL看起来像这样:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="k" match="somechild" use="@child-id"/>
<xsl:key name="n" match="node" use="somechild/@child-id"/>
<xsl:template match="root/highernode">
<xsl:copy>
<xsl:copy-of select="highernodename"/>
<xsl:copy-of select="highernodeId"/>
<xsl:apply-templates
select="//somechild[generate-id(.) = generate-id(key('k', @child-id))]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="somechild">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="key('n', @child-id)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node">
<xsl:copy>
<xsl:apply-templates select="@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果如下:
<highernode>
<highernodename>Name1</highernodename>
<highernodeId>Id1</highernodeId>
<somechild>1<node>node1</node>
<node>node3</node>
<node>node1</node>
</somechild>
<somechild>2<node>node2</node>
<node>node4</node>
</somechild>
<somechild>3<node>node5</node>
<node>node5</node>
</somechild>
<somechild>5<node>node2</node>
<node>node3</node>
</somechild>
<somechild>4<node>node6</node>
</somechild>
</highernode>
<highernode>
<highernodename>Name2</highernodename>
<highernodeId>Id2</highernodeId>
<somechild>1<node>node1</node>
<node>node3</node>
<node>node1</node>
</somechild>
<somechild>2<node>node2</node>
<node>node4</node>
</somechild>
<somechild>3<node>node5</node>
<node>node5</node>
</somechild>
<somechild>5<node>node2</node>
<node>node3</node>
</somechild>
<somechild>4<node>node6</node>
</somechild>
</highernode>
如您所见,有两个问题: 1)在每个较高节点中,它从所有较高节点而不是当前节点带来“somechild”和“node” 2)它在自己的值之后命令“somechild”(参见highnode2,somechild3应该是last,但它不是。
我希望我已经足够清楚。
谢谢你, 米哈伊
答案 0 :(得分:0)
如果要在每个节点中单独执行此类Muenchian分组,则需要在用于分组的键值中包含父节点特有的内容,例如:
<xsl:key name="k" match="somechild"
use="concat(../../highernodeId, '|', @child-id)"/>
<xsl:key name="n" match="node"
use="concat(../highernodeId, '|', somechild/@child-id)"/>
,当您取消引用密钥时也一样:
<xsl:template match="root/highernode">
<xsl:copy>
<xsl:copy-of select="highernodename"/>
<xsl:copy-of select="highernodeId"/>
<xsl:apply-templates
select="node/somechild[generate-id(.) = generate-id(
key('k', concat(current()/highernodeId, '|', @child-id)))]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="somechild">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="key('n',
concat(../../highernodeId, '|', @child-id))"/>
</xsl:copy>
</xsl:template>