2011-08-15 223 views
2

我正在查看Muenchian分组。我试图找到类似于我的XML的例子,但找不到任何。大部分的例子结构合理,而我的混乱。XSLT 1.0分组密钥用于不同的节点和元素

下面是我的XML的简短版本(注意,我无法更改XML结构,因为它是标准的东西,而且不在我的手中),并且我使用的是XSLT 1,因为系统现在只支持该版本。

<object> 
    <creator id="123"> 
     <name>ABC</name> 
     <city>Hamilton</city> 
    </creator> 
    <creator><references>456</references></creator> 
    <contact><references>123</references></contact> 
    <creator id="456"> 
     <name>XYZ</name> 
     <city>New York</city> 
    </creator> 
    <associatedParty><references>123</references> 
     <role>Sponsor</role> 
    </associatedParty> 
</object> 

,我希望的输出是:

<party id="123"> 
     <name>ABC</name> 
     <city>Hamilton</city> 
     <role>Creator</role> 
     <role>Contact</role> 
     <role>Sponsor</role> 
    </party> 
    <party id="456"> 
     <name>XYZ</name> 
     <city>New York</city> 
     <role>Creator</role> 
     <role>Contact</role> 
    </party> 

现在id属性被用作参考元件的值。并且输出中的标记可以是创建者,联系人或元素内的任何元素(如果它位于associatedParty元素下)。

我一直在创建密钥以将它们从它们的id/references属性中分组。据我所见,使用xsl:key的例子仅适用于具有相同名称的节点,并且我发布的示例具有不同的节点名称。任何帮助,将不胜感激!!!!

+0

问得好,+1。查看我的答案获得完整的解决方案。 –

回答

1

这种转变

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:key name="kRefByVal" match="references" 
    use="."/> 

<xsl:key name="kCreatorById" match="creator" 
    use="@id"/> 

<xsl:key name="kRoleNameByRef" 
     match="*[not(self::associatedParty 
        or 
        self::creator 
        ) 
       ]" 
     use="references"/> 

<xsl:key name="kAssocByRef" 
     match="associatedParty" 
     use="references"/> 

<xsl:template match="/"> 
    <xsl:variable name="vReferences" select= 
    "*/*/references 
     [generate-id() 
     = 
      generate-id(key('kRefByVal',.)[1]) 
     ] 
    "/> 

    <xsl:apply-templates select="$vReferences"> 
    <xsl:sort select="." data-type="number"/> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="references" priority="3"> 
    <party id="{.}"> 
    <xsl:copy-of select="key('kCreatorById',.)/*"/> 
    <xsl:apply-templates select= 
    "key('kCreatorById',.)"/> 

    <xsl:apply-templates select= 
    "key('kRoleNameByRef',.)"/> 

    <xsl:copy-of select="key('kAssocByRef',.)/role"/> 
    </party> 
</xsl:template> 

<xsl:template match="*[not(self::associatedParty)]"> 
    <role> 
    <xsl:value-of select="name()"/> 
    </role> 
</xsl:template> 
</xsl:stylesheet> 

时所提供的XML文档应用:

<object> 
    <creator id="123"> 
     <name>ABC</name> 
     <city>Hamilton</city> 
    </creator> 
    <creator> 
     <references>456</references> 
    </creator> 
    <contact> 
     <references>123</references> 
    </contact> 
    <creator id="456"> 
     <name>XYZ</name> 
     <city>New York</city> 
    </creator> 
    <associatedParty> 
     <references>123</references> 
     <role>Sponsor</role> 
    </associatedParty> 
</object> 

产生想要的,正确的结果

<party id="123"> 
    <name>ABC</name> 
    <city>Hamilton</city> 
    <role>creator</role> 
    <role>contact</role> 
    <role>Sponsor</role> 
</party> 
<party id="456"> 
    <name>XYZ</name> 
    <city>New York</city> 
    <role>creator</role> 
</party> 
+0

感谢您的回答:)!!!!尽管我还没有完全理解它们究竟意味着什么 – Yun

0

您可以使用此模板:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="//creator[not(references)]"/> 
    </xsl:template> 

    <xsl:template match="creator"> 
    <party id="{@id}"> 
     <xsl:copy-of select="name"/> 
     <xsl:copy-of select="city"/> 
     <role>Creator</role> 
     <xsl:apply-templates select="../*[not(self::creator) and references = current()/@id]"/> 
    </party> 

    </xsl:template> 

    <xsl:template match="associatedParty" priority="1"> 
    <xsl:copy-of select="role"/> 
    </xsl:template> 

    <xsl:template match="*[references]"> 
    <role> 
     <xsl:value-of select="name()"/> 
    </role> 
    </xsl:template> 

</xsl:stylesheet> 

输出:

<party id="123"> 
    <name>ABC</name> 
    <city>Hamilton</city> 
    <role>Creator</role> 
    <role>contact</role> 
    <role>Sponsor</role> 
</party> 
<party id="456"> 
    <name>XYZ</name> 
    <city>New York</city> 
    <role>Creator</role> 
</party> 
+0

感谢您的回答!它也工作!我想知道有没有人可以给出这两种方法的概述。如果有任何比另一个更好的性能。 – Yun