2011-02-12 168 views
2

使用XSLT,我想弄清楚如何合併/更新一組節點中的數據與另一組節點中的數據。節點具有相同的模式,但父母不同。數據需要根據共享的父屬性進行合併。在下面的示例中,數據正在從主體複製到驅動程序。有人可以幫我從這裏出去嗎?使用XSLT將數據從XML節點合併到另一個節點

輸入文件:

<Info> 
    <Principal id="Insured"> 
    <PersonName> 
     <GivenName>Jane</GivenName> 
     <OtherGivenName>A</OtherGivenName> 
     <Surname>Doe</Surname> 
    </PersonName> 
    <PersonInfo> 
     <BirthDate>01-01-1980</BirthDate> 
     <MaritalStatus>M</MaritalStatus> 
    </PersonInfo> 
    <PrincipalInfo></PrincipalInfo> 
    </Principal> 
    <Policy> 
    <Driver id="Insured"> 
     <PersonName> 
     <GivenName>Jane</GivenName> 
     <Surname>Smith</Surname> 
     </PersonName> 
     <PersonInfo> 
     <BirthDate>01-01-1980</BirthDate> 
     <MaritalStatus>S</MaritalStatus> 
     <Occupation>Manager</Occupation> 
     </PersonInfo> 
    </Driver> 
    <PolicyInfo></PolicyInfo> 
    </Policy> 
</Info> 

所需的結果:

<Info> 
    <Principal id="Insured"> 
    <PersonName> 
     <GivenName>Jane</GivenName> 
     <OtherGivenName>A</OtherGivenName> 
     <Surname>Doe</Surname> 
    </PersonName> 
    <PersonInfo> 
     <BirthDate>01-01-1980</BirthDate> 
     <MaritalStatus>M</MaritalStatus> 
    </PersonInfo> 
    <PrincipalInfo></PrincipalInfo> 
    </Principal> 
    <Policy> 
    <Driver id="Insured"> 
     <PersonName> 
     <GivenName>Jane</GivenName> 
     <OtherGivenName>A</OtherGivenName> 
     <Surname>Doe</Surname> 
     </PersonName> 
     <PersonInfo> 
     <BirthDate>01-01-1980</BirthDate> 
     <MaritalStatus>M</MaritalStatus> 
     <Occupation>Manager</Occupation> 
     </PersonInfo> 
    </Driver> 
    <PolicyInfo></PolicyInfo> 
    </Policy> 
</Info> 
+0

這是真的嗎?你基本上用新值替換PersonName。沒有合併發生。 – Flack 2011-02-12 16:42:06

+0

驅動程序子節點中可能存在額外的節點,我想離開,因此只更換整個節點不起作用。注意我的例子中的。 – 2011-02-12 17:02:45

回答

2

這裏是一個完整的解決方案

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

<xsl:key name="kPrincipalById" match="Principal" 
    use="@id"/> 

<xsl:key name="kPrincipalChild" match="Principal/*/*" 
    use="concat(../../@id, name())"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="Driver/*"> 
    <xsl:variable name="vPrincipal" 
    select="key('kPrincipalById', ../@id)"/> 

    <xsl:copy> 
    <xsl:apply-templates select="@*"/> 
    <xsl:apply-templates select= 
    "$vPrincipal/*[name()=name(current())]/*"/> 
    <xsl:apply-templates select= 
    "*[not(key('kPrincipalChild', 
       concat(../../@id,name()) 
       ) 
      ) 
     ]"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

當這種轉變是在所提供的XML文檔應用:

<Info> 
    <Principal id="Insured"> 
     <PersonName> 
      <GivenName>Jane</GivenName> 
      <OtherGivenName>A</OtherGivenName> 
      <Surname>Doe</Surname> 
     </PersonName> 
     <PersonInfo> 
      <BirthDate>01-01-1980</BirthDate> 
      <MaritalStatus>M</MaritalStatus> 
     </PersonInfo> 
     <PrincipalInfo></PrincipalInfo> 
    </Principal> 
    <Policy> 
     <Driver id="Insured"> 
      <PersonName> 
       <GivenName>Jane</GivenName> 
       <Surname>Smith</Surname> 
      </PersonName> 
      <PersonInfo> 
       <BirthDate>01-01-1980</BirthDate> 
       <MaritalStatus>S</MaritalStatus> 
       <Occupation>Manager</Occupation> 
      </PersonInfo> 
     </Driver> 
     <PolicyInfo></PolicyInfo> 
    </Policy> 
</Info> 

想要的,正確的結果產生:

<Info> 
    <Principal id="Insured"> 
     <PersonName> 
     <GivenName>Jane</GivenName> 
     <OtherGivenName>A</OtherGivenName> 
     <Surname>Doe</Surname> 
     </PersonName> 
     <PersonInfo> 
     <BirthDate>01-01-1980</BirthDate> 
     <MaritalStatus>M</MaritalStatus> 
     </PersonInfo> 
     <PrincipalInfo/> 
    </Principal> 
    <Policy> 
     <Driver id="Insured"> 
     <PersonName> 
      <GivenName>Jane</GivenName> 
      <OtherGivenName>A</OtherGivenName> 
      <Surname>Doe</Surname> 
     </PersonName> 
     <PersonInfo> 
      <BirthDate>01-01-1980</BirthDate> 
      <MaritalStatus>M</MaritalStatus> 
      <Occupation>Manager</Occupation> 
     </PersonInfo> 
     </Driver> 
     <PolicyInfo/> 
    </Policy> 
</Info> 

說明

  1. identity rule /模板拷貝的每一個節點 「原樣」 。身份規則的使用和重寫是最基本和最強大的XSLT設計模式。

  2. 只有一個附加模板覆蓋子標識規則 - Driver的元素。它複製(並有效地替換Driver的同名grand-child元素與相應的)Principal的grand-child元素。然後,它仍然處理(份)的Driver那些盛大的子元素沒有相應的盛大兒童和Principal

  3. 元素方便地訪問Principal其盛大的孩子 - 通過ID和id ++名稱(),有兩個keys定義爲並使用。

相關問題