2017-02-27 14 views
0

変更されたノードのリストを取得したいとします(ノードの追加とノードの更新)。C#:2つのXMLファイルの差分 - 変更/更新されたノードのみを取得する

これは、(更新前と後)

私のプログラムおよびXMLファイルであるfileBeforeUpdate.xml

<?xml version="1.0"?> 
<DESCRIPTION> 
    <DISTRIBUE_PAR> 
     <UID>0000000000001</UID> 
     <NOM>Anthony</NOM> 
    </DISTRIBUE_PAR> 
    <OBJET>Object Node</OBJET> 
    <SUPPORT HREF="#PAPER"/> 
    <NUMEROS_CHRONO> 
     <CHRONO_1>aqwzsxedc-123456</CHRONO_1> 
    </NUMEROS_CHRONO> 
    <REFERENCE>reference</REFERENCE> 
</DESCRIPTION> 

fileAfterUpdate.xml

<?xml version="1.0"?> 
<DESCRIPTION> 
    <DISTRIBUE_PAR> 
     <NOM>Antoni</NOM> 
    </DISTRIBUE_PAR> 
    <OBJET>Object Node</OBJET> 
    <SUPPORT HREF="#MAIL"/> 
    <NUMEROS_CHRONO> 
     <CHRONO_1>aqwzsxedc-123456</CHRONO_1> 
    </NUMEROS_CHRONO> 
    <REFERENCE>reference</REFERENCE> 
    <DATE>01/03/1994</DATE> 
</DESCRIPTION> 

Program.csの

var sb = new StringBuilder(); 
using (XmlWriter xmlWriter = XmlWriter.Create(sb)) 
{ 
    XmlDiff diff = new XmlDiff(XmlDiffOptions.IgnoreComments | XmlDiffOptions.IgnoreWhitespace | XmlDiffOptions.IgnoreNamespaces); 
    diff.Compare(@"C:\fileBeforeUpdate", @"C:\fileAfterUpdate", true, xmlWriter); 
    diff.Algorithm = XmlDiffAlgorithm.Precise; 

    XmlDocument doc = new XmlDocument(); 
    doc.LoadXml(sb.ToString()); 
} 

これはStringBuilder出力は次のとおり

<xd:node match=\"1\"> 
    <xd:node match=\"1\"> 
     <xd:remove match=\"1\" /> 
     <xd:node match=\"2\"> 
      <xd:change match=\"1\">Antoni</xd:change> 
     </xd:node> 
    </xd:node> 
    <xd:node match=\"3\"> 
     <xd:change match=\"@HREF\">#MAIL</xd:change> 
    </xd:node> 
    <xd:node match=\"5\" /> 
    <xd:add> 
     <DATE>01/03/1994</DATE> 
    </xd:add> 
</xd:node> 

追加されたノードのリストを取得するため、それは容易だ(StringBuilderに、私は追加されたノードとノード<xd:add>及び値を有します)。

var addNodes = doc.GetElementsByTagName("xd:add"); 
var xmlNodesAdded = new StringBuilder(); 

foreach (XmlNode node in addNodes) 
{ 
     xmlNodesAdded.Append(node.InnerXml); 
     xmlNodesAdded.AppendLine(); 
} 

ただし、変更されたノード(および属性)のリストを取得するために、それはより困難だ...

どのように私はこれを達成することができますか? StringBuilder
は、ノードxd:changeが更新されたノードを指定しない...

は、事前にありがとうございます。

+0

を私は_well-formed_であるためにあなたのXMLファイルの両方を完了しました。 – zx485

+0

diffgram形式の詳細については、 https://msdn.microsoft.com/en-us/library/aa302295.aspx を参照してください。コードスニペットには、処理方法を示すものもあります。また、XmlDiffViewクラスのソースコードについては、https://github.com/fschwiet/PSUpdateXml/blob/master/tools/XmlDiffPatch/Samples/XmlDiffView/XmlDiffView.csを参照してください。幸運;) – Rogn

+0

私はこのドキュメントを読んだが、彼女は私を助​​けなかった。私はどのように変更されているノード名を取得するために行うことができますが見つかりませんでした... – Dooxe

答えて

0

XmlDiffViewを使用すると、変更のHTMLプレゼンテーションを取得できます。 (場合によっては、変更タイプが正しく認識されません)。

public string GetChangeHtml(string originalXML, string changedXML) 
{ 
    XmlDiffView view = new XmlDiffView(); 
    var diffgram = Diff(originalXML, changedXML); 
    string ret = ""; 
    using (StringReader legacySr = new StringReader(originalXML), diffGramSr = new StringReader(diffgram.ToString())) 
    { 
     using (XmlReader legacyReader = XmlReader.Create(legacySr), diffgramReader = XmlReader.Create(diffGramSr)) 
     { 
      using (StringWriter sw = new StringWriter()) 
      { 
       view.Load(legacyReader, diffgramReader); 
       view.GetHtml(sw); 
       ret = sw.ToString(); 
      } 
     } 
    } 
    return ret; 
} 

下の私の質問にコードを確認してください: XMLDiff fails to recognize differences correcly?

関連する問題