2013-02-20 55 views
2

我必須將節點元素的數據從file1.xml複製到file2.xml。 file1.xml使用XSLT將數據從一個XML文檔複製到另一個

<?xml version="1.0" encoding="utf-8" ?> 
<root> 
    <header> 
    <AsofDate>31-Dec-2012</AsofDate> 
    <FundName>This is Sample Fund</FundName> 
    <Description>This is test description</Description> 
    </header> 
</root> 

file2.xml

<?xml version="1.0" encoding="utf-8" ?> 
<root id="1"> 
    <header id="2"> 
    <AsofDate id="3"/> 
    <FundName id="4" /> 
    <Description id="5" /> 
    </header> 
</root> 

合併file1.xml到file2.xml後,結果應該看看下面:

<?xml version="1.0" encoding="utf-8" ?> 
<root id="1"> 
    <header id="2"> 
    <AsofDate id="3">31-Dec-2012</AsofDate> 
    <FundName id="4">This is Sample Fund</FundName> 
    <Description id="5">This is test description</Description> 
    </header> 
</root> 

我使用在XSLT下面轉換文件。

<?xml version="1.0" encoding="utf-8" ?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()" /> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

下面是代碼用於執行變換:

XslCompiledTransform tf = new XslCompiledTransform(); 
    tf.Load("TranFile.xsl"); 

    tf.Transform("file1.xml", "file2.xml"); 

但上面的代碼重寫file2的內容與內容file1.xml。這只是示例XML。在實際情況下,我們不知道XML文件的節點和層次結構的名稱。但是無論哪種結構對於文件和場景都是一樣的,都是完全相同的。我是XSLT新手,不確定這是否是正確的方法來完成結果。是否真的有可能通過XSLT實現結果。

+0

的可能重複的[XSLT:一個簡單的方式來合併XML文件(http://stackoverflow.com/questions/1510688/xslt-a-simple-way-to-merge-xml-files) – iTech 2013-02-20 20:18:43

+0

這裏我不知道來自服務的XML結構。 – Nps 2013-02-20 20:26:06

+0

我想,在真實情況下,file2.xml中的id不會是順序的,不是?我的意思是你會發現像

...順便說一句,你是否嘗試使用文檔('')函數? – 2013-02-20 22:54:11

回答

4

,我發佈的解決方案是寫銘記以下幾點:

  • 需要合併的唯一的事情是屬性。文本和元素節點在從file1.xml中出現時被複制。

  • 的@id屬性不是在file2.xml依次編號所以@ ID在file2.xml可以是(例如)121 432 233 12 944,而不是1 2 3 4 5。如果情況後者則不需要file2.xml來生成所需的輸出。

  • 可以使用document()函數來訪問不同於當前文件的文件。如果XslCompiledTransform在使用文檔功能時發生錯誤,我會建議遵循此using document() function in .NET XSLT generates error。我正在使用不同的XSLT處理器(xsltproc),它工作正常。

該解決方案是基於保持到外部文件的引用,因此每個我們在file1.xml基準處理的元件的時間被移動在file2.xml同一元素指向。這可以這樣做,因爲根據問題,這兩個文件呈現相同的元素層次結構。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" indent="no"/> 

    <!-- Match the document node as an entry point for matching the files --> 
    <xsl:template match="/"> 
     <xsl:apply-templates select="node()"> 
      <xsl:with-param name="doc-context" select="document('file2.xml')/node()" /> 
     </xsl:apply-templates> 
    </xsl:template> 

    <!-- In this template we copy the elements and text nodes from file1.xml and 
     we merge the attributes from file2.xml with the attributes in file1.xml --> 
    <xsl:template match="node()"> 
     <!-- We use this parameter to keep track of where we are in file2.xml by 
      mimicking the operations that we do in the current file. So we are at 
      the same position in both files at the same time. --> 
     <xsl:param name="doc-context" /> 

     <!-- Obtain current position in file1.xml so we know where to look in file2.xml --> 
     <xsl:variable name="position" select="position()" /> 

     <!-- Copy the element node from the current file (file1.xml) --> 
     <xsl:copy> 
      <!-- Merge attributes from file1.xml with attributes from file2.xml --> 
      <xsl:copy-of select="@*|$doc-context[position() = $position]/@*" /> 
      <!-- Copy text nodes and process children --> 
      <xsl:apply-templates select="node()"> 
       <xsl:with-param name="doc-context" select="$doc-context/node()" /> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

非常感謝,這個解決方案完美解決了這個問題。 – Nps 2013-02-21 04:42:37

+0

我想知道,如果兩個xml文件都不是物理文件,我們如何實現相同的解決方案。如果這些是從數據庫代碼生成的。 – Nps 2013-02-21 05:01:38

+0

很高興看到XSLT中的一些評論。 – Sepster 2016-08-16 22:45:51

相關問題