2011-02-12 97 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定义为并使用。

相关问题