2011-08-15 403 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