2008-11-29 43 views
2

這是我的問題。我有2個xmlfiles具有相同的結構,第二個xml僅包含與第一個相比較少的節點。比較2個XML文檔並將更改應用到源文檔

文件1

<root> 
    <alpha>111</alpha> 
    <beta>22</beta> 
    <gamma></gamma> 
    <delta></delta> 
    </root> 

文件2

<root> 
    <beta>XX</beta> 
    <delta>XX</delta> 
</root> 

這是結果應該是什麼樣子

<root> 
    <alpha>111</alpha> 
    <beta>22</beta> 
    <gamma></gamma> 
    <delta>XX</delta> 
</root> 

基本上,如果File1中的任何節點的節點內容是空白的,然後它應該讀取來自File2的值(如果存在的話,帽子是)。

我用Microsoft XmlDiff API嘗試了我的運氣,但它並沒有爲我工作(補丁程序沒有對源文件應用更改)。另外我有點擔心它使用的DOM方法,因爲我將處理的xml的大小。 你可以請建議一個這樣做的好方法。 我正在使用C#2

回答

2

下面是該提出的阿拉斯泰爾(見我對他的解決辦法評論)有點更簡單,更有效的解決方案。

這種變換:

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

    <xsl:variable name="vFile2" 
     select="document('File2.xml')"/> 

    <xsl:template match="*"> 
     <xsl:copy> 
     <xsl:copy-of select="@*"/> 
      <xsl:apply-templates/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="*[not(text())]"> 
     <xsl:copy> 
     <xsl:copy-of 
      select="$vFile2/*/*[name() = name(current())]/text()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

當此XML文檔上施加:

 
<root> 
    <alpha>111</alpha> 
    <beta>22</beta> 
    <gamma></gamma> 
    <delta></delta> 
</root> 

產生想要的結果:

 
<root> 
    <alpha>111</alpha> 
    <beta>22</beta> 
    <gamma></gamma> 
    <delta>XX</delta> 
</root> 
+0

這工作正常。謝謝Dimitre – HashName 2008-12-01 19:13:06

1

此合併似乎非常具體。

如果是這樣,只需編寫一些代碼來加載這兩個xml文件並按照您所描述的那樣應用更改。

2

在XSLT中,如果遇到File1中的空節點,則可以使用document()函數從File2中檢索節點。喜歡的東西:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:template match="root/*[.='']"> 
    <xsl:variable name="file2node"> 
     <xsl:copy-of select="document('File2.xml')/root/*[name()=name(current())]"/> 
    </xsl:variable> 
    <xsl:choose> 
     <xsl:when test="$file2node != ''"> 
     <xsl:copy-of select="$file2node"/> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:copy/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

    <xsl:template match="*"> 
    <xsl:copy> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates/> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

第一個模板,尤其是這樣的表達式:「根/*[.='']「可能非常昂貴,因爲它們需要計算任何元素的完整字符串內容,這是res超鏈接此元素的所有文本節點後代。這意味着完整的子樹將被遍歷。 – 2008-11-29 16:21:10