2014-09-30 190 views
0

我想合併2 xml文件(作爲代碼中的字符串)。XSL轉換 - 合併元素

<Root> 
    <AMA> 
     <Profile> 
      <UniqueID id="3"/> 
      <Name type="UN">TOTO</Name> 
      <Address>AAA</Address> 
     </Profile> 
     <Profile> 
      <UniqueID id="4"/> 
      <Name>TOTA</Name> 
      <Address>BBB</Address> 
     </Profile> 
     <Profile> 
      <UniqueID id="5"/> 
      <Name>TOTQ</Name> 
     </Profile> 
     <Profile> 
      <UniqueID id="6"/> 
      <Name>TOTG</Name> 
     </Profile> 
     <Profile> 
      <UniqueID id="7"/> 
      <Name>TOTB</Name> 
      <Address>CCC</Address> 
     </Profile> 
    </AMA> 
    <External> 
     <Profile> 
      <UniqueID id="3"/> 
      <Miles>5</Miles> 
     </Profile> 
     <Profile> 
      <UniqueID id="4"/> 
      <Miles>4</Miles> 
<Points>22222</Points> 
     </Profile> 
     <Profile> 
      <UniqueID id="5"/> 
      <Miles>3</Miles> 
     </Profile> 
     <Profile> 
      <UniqueID id="6"/> 
      <Miles>2</Miles> 
     </Profile> 
     <Profile> 
      <UniqueID id="7"/> 
      <Miles>1</Miles> 
     </Profile> 
    </External> 
</Root> 

我想獲得

<?xml version="1.0" encoding="ISO-8859-1"?> 
<Root> 
    <Profile> 
     <UniqueID id="3"/> 
     <Name type="UN">TOTO</Name> 
     <Address>AAA</Address> 
     <Miles>5</Miles> 
    </Profile> 
    <Profile> 
     <UniqueID id="4"/> 
     <Name>TOTA</Name> 
     <Address>BBB</Address> 
     <Miles>4</Miles> 
     <Points>22222</Points> 
    </Profile> 
    <Profile> 
     <UniqueID id="5"/> 
     <Name>TOTQ</Name> 
     <Miles>3</Miles> 
    </Profile> 
    <Profile> 
     <UniqueID id="6"/> 
     <Name>TOTG</Name> 
     <Miles>2</Miles> 
    </Profile> 
    <Profile> 
     <UniqueID id="7"/> 
     <Name>TOTB</Name> 
     <Address>CCC</Address> 
     <Miles>1</Miles> 
    </Profile> 
</Root> 

我設法寫類似:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes" /> 
    <Root> 
    <xsl:template match="/Root/AMA/Profile"> 
     <Profile> 
      <xsl:for-each select="."> 
       <xsl:copy-of select="@*|node()"/> 
       <xsl:copy-of select="/Root/External/Profile/UniqueID[@id=current()/UniqueID/@id]/../(Miles|Points)"/> 
      </xsl:for-each> 
     </Profile> 
    </xsl:template> 
    <xsl:template match="/root/External"/> 
</xsl:transform> 
    </Root> 

這怎麼可能避免 「硬編碼」 配置文件的節點?

通過「硬編碼」我的意思是「不放在XML轉換的資料元素標籤打開和關閉了我的手,只是配置文件節點從原來的一個副本。

看來另一種方法存在,使用在XSLT Lookup Tableshere ......但似乎有點矯枉過正。

你認爲這是一個更好的解決辦法?

+0

您可否詳細說明一下?什麼是「配置文件節點硬編碼」? – 2014-10-01 01:48:03

+0

我真的不知道你在問什麼。您向我們展示了一個單一的輸入文檔,而不是您所說的使用的兩個文檔,而且您還沒有真正給出我們對您要合併的內容的完整說明。我同意@KirillPolishchuk的說法,即「硬編碼Profile節點」並不清楚你的意思 - 你現在的做法不能做什麼?此外,請注意,您的樣式表格格式不正確 - Root元素沒有正確嵌套,沒有根節點模板來啓動匹配過程,但由於它具有模板,因此它不是拉式樣式表。停止並定義問題。 – keshlam 2014-10-01 04:05:21

+0

是的,有一個更好的解決方案:使用**鍵**來查找外部值。不,它與「*避免」硬編碼「配置文件節點*」無關 - 您的請求的這一部分並不清晰,正如其他人已經注意到的那樣。 - 還要注意''>'什麼都不做。 – 2014-10-01 05:14:20

回答

1

它看起來就像你正在試圖做的是要合併的AMAProfile兒童和External

你已經差不多了,但你需要移動Root,刪除xsl:for-each並更新select在第二個xsl:copy-of。 (我在我的例子移動的固定路徑到第一xsl:copy-of。)

像這樣...(在你的XPath假設XSLT 2.0,因爲(Miles|Points)

XSLT 2.0

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

    <!--This will handle <Root/>--> 
    <xsl:template match="/*"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|AMA/Profile"/> 
     </xsl:copy>   
    </xsl:template> 

    <xsl:template match="/Root/AMA/Profile"> 
     <Profile> 
      <xsl:copy-of select="@*|node()| 
      /*/External/Profile[UniqueID/@id=current()/UniqueID/@id]/(Miles|Points)"/> 
     </Profile> 
    </xsl:template> 

</xsl:stylesheet> 

如果您需要切換到XSLT 1.0,請將(Miles|Points)更改爲*[self::Miles or self::Points]

+0

如果里程和積分屬於個人資料的內部元素,我希望將他們保持在相同的深度,那麼情況如何? – lucabelluccini 2014-10-06 09:16:28