XSLT:复制除中间元素之外的所有内容

时间:2013-10-15 15:27:56

标签: xml xslt

这是大型xml转换的一部分。
输入Xml

<Root>
 <Family>
   <Entity>
     <SomeElement1/>
     <ClientVO>
     <FirstName>Himanshu</FirstName>
     <LastName>Yadav</LastName>
     <ClientAddress>
      <AddressLine>Somewhere In downtown</AddressLine>
      <City>Chicago</City>
      <State>IL</State>
     </ClientAddress>
    </ClientVO>
     <Child2>
       <Element2/>
     </Child2>
     <Entity>
     <SomeElement1/>
     <ClientVO>
     <FirstName>Himanshu</FirstName>
     <LastName>Yadav</LastName>
     <ClientAddress>
      <AddressLine>Somewhere In downtown</AddressLine>
      <City>Chicago</City>
      <State>IL</State>
     </ClientAddress>
    </ClientVO>
     <Child2>
       <Element222/>
     </Child2>
   </Entity>
  </Entity>
 </Family>
</Root>

输出Xml

<Response>
 <EntityRoot>
  <SomeElement1/>
 </EntityRoot>

 <ClientInformation>
     <FirstName>Himanshu</FirstName>
     <LastName>Yadav</LastName>
     <AddressLine>Somewhere In downtown</AddressLine>
     <City>Chicago</City>
     <State>IL</State>
    </ClientInformation>

 <Child2Root>
   <Element2>
 </Child2Root>

 <MetadataEntityRoot>
  <SomeElement1/>
 </MetadataEntityRoot>

 <ClientInformation>
     <FirstName>Himanshu</FirstName>
     <LastName>Yadav</LastName>
     <AddressLine>Somewhere In downtown</AddressLine>
     <City>Chicago</City>
     <State>IL</State>
    </ClientInformation>

 <Child2Root>
   <Element222>
 </Child2Root>
</Response>

尝试下面的xslt,但不是一个可行的解决方案,因为<ClientVO><ClientAddress>下可能有更多元素。它更像是一对一的映射,我想避免。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
   </xsl:template>
    <xsl:template match="Entity">
      <EntityRoot>
        <xsl:apply-templates select="@* | node()[not(self::ClientVO| self::Child2)]" />
      </EntityRoot>
      <xsl:apply-templates select="ClientVO| Child2" />
    </xsl:template>
    <xsl:template match="ClientVO">
      <ClientInformation>
       <FirstName><xsl:value-of select="FirstName"/></FirstName>
       <LastName><xsl:value-of select="LastName"/></LastName>
       <xsl:for-each select="ClientAddress">
         <AddressLine><xsl:value-of select="AddressLine"/></AddressLine>
         <City><xsl:value-of select="City"/></City>
         <State><xsl:value-of select="State"/></State>
       </xsl:for-each>
      </ClientInformation>
    </xsl:template>
    <xsl:template match="Child2">
      <Child2Root><xsl:apply-templates select="@*|node()" /></Child2Root>
    </xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:1)

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

<xsl:template match="ClientAddress">
  <xsl:apply-templates />
</xsl:template>

如果您想以1:1映射大多数内容,请从身份模板开始并根据需要覆盖它。

答案 1 :(得分:1)

这是同一模式的另一个实例,它是您最后几个问题的答案 - 让身份模板为您完成大部分工作,并在需要时覆盖它。在这种情况下,您需要将ClientVO重命名为ClientInformation

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

并跳过ClientAddress但继续处理其子项

<xsl:template match="ClientAddress">
  <xsl:apply-templates />
</xsl:template>