2013-05-26 47 views
0

我有下面的輸入XML:XSLT防止或消除多次引用

<?xml version="1.0" encoding="UTF-8"?> 
<persons> 
    <person id="1" type="parent"> 
     <name>father</name> 
     <person-reference type="child">3</person-reference> 
     <person-reference type="child">4</person-reference> 
    </person> 
    <person id="2" type="parent"> 
     <name>mother</name> 
     <person-reference type="child">3</person-reference> 
     <person-reference type="child">4</person-reference> 
    </person> 
    <person id="3"> 
     <name>brother</name> 
    </person> 
    <person id="4"> 
     <name>sister</name> 
    </person> 
</persons> 

有以下XSLT轉換:

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:stylesheet version="2.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/persons"> 
     <relations> 
      <xsl:apply-templates select="person[@type = 'parent']"/> 
     </relations> 
    </xsl:template> 

    <xsl:template match="person"> 
     <parent> 
      <name><xsl:value-of select="name"/></name> 
     </parent> 

     <xsl:apply-templates select="person-reference[@type = 'child']"/> 
    </xsl:template> 

    <xsl:template match="person-reference"> 
     <child> 
      <name><xsl:value-of select="//person[@id = current()]/name"/></name> 
     </child> 
    </xsl:template> 
</xsl:stylesheet> 

我得到這個XML(結果):

<?xml version="1.0" encoding="UTF-8"?> 
<relations xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <parent> 
     <name>father</name> 
    </parent> 
    <child> 
     <name>brother</name> 
    </child> 
    <child> 
     <name>sister</name> 
    </child> 
    <parent> 
     <name>mother</name> 
    </parent> 
    <child> 
     <name>brother</name> 
    </child> 
    <child> 
     <name>sister</name> 
    </child> 
</relations> 

但我想這是XML(預期結果):

<?xml version="1.0" encoding="UTF-8"?> 
<relations xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <parent> 
     <name>father</name> 
    </parent> 
    <child> 
     <name>brother</name> 
    </child> 
    <child> 
     <name>sister</name> 
    </child> 
    <parent> 
     <name>mother</name> 
    </parent> 
</relations> 

還是這個(可選預期結果):

<?xml version="1.0" encoding="UTF-8"?> 
<relations xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <parent> 
     <name>father</name> 
    </parent> 
    <parent> 
     <name>mother</name> 
    </parent> 
    <child> 
     <name>brother</name> 
    </child> 
    <child> 
     <name>sister</name> 
    </child> 
</relations> 

是否有與XSLT方法,以防止使用引用像我這樣做雙頭輸出?

+0

我認爲你必須更多在這裏解釋一下。因爲你預期的輸出可以很容易地通過只希望類型的人屬性忽略任何人引用和ID生成。但從長遠來看,這很可能無濟於事。 –

+0

好點。我已經編輯了一下這個例子。預期的產出確實需要通過人員參考。 – Tuno

+0

丹尼斯,你使用XSLT 2.0處理器(如您已使用'版本= 「2.0」'您'的xsl:stylesheet'元)?並且能有多層次的父母/子女關係嗎? –

回答

1

爲了防止重複人引用(使用XSLT-1.0),可以使用xsl-key

<xsl:key name="kReference" match="person-reference" use="."/> 

並測試當前引用是否是第一個引用。

<xsl:if test=" generate-id()= generate-id(key('kReference', current()/text())[1])" > 

爲此試試這個:

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:key name="kReference" match="person-reference" use="."/> 

    <xsl:template match="/persons"> 
     <relations> 
      <xsl:apply-templates select="person[@type = 'parent']"/> 
     </relations> 
    </xsl:template> 

    <xsl:template match="person"> 
     <parent> 
      <name> 
       <xsl:value-of select="name"/> 
      </name> 
     </parent> 

     <xsl:apply-templates select="person-reference"/> 
    </xsl:template> 

    <xsl:template match="person-reference"> 
     <xsl:if test=" generate-id()= generate-id(key('kReference', current()/text())[1])" > 
      <child> 
       <name> 
        <xsl:value-of select="//person[@id = current()]/name"/> 
       </name> 
      </child> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

但我仍擔心有更多這背後的問題。

+0

你是對的。在完整複雜的XSLT中,這個問題背後更多。我用一個簡單的例子解釋了這個部分,並整合了你的解決方案。它確實有效。謝謝。 – Tuno