比较两个XML文件和放大器;产生第三位的xmldiff在C# [英] Comparing two XML files & generating a third with XMLDiff in C#

查看:103
本文介绍了比较两个XML文件和放大器;产生第三位的xmldiff在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图写一个简单的算法来阅读完全相同的节点和结构,但并不一定是子节点内相同的数据,而不是按相同的顺序两个XML文件。 ?我怎么能创建创建第三个,临时XML是两个第一批之间的差异,使用微软的XML DIFF .DLL一个简单的实现。

I am trying to write a simple algorithm to read two XML files with the exact same nodes and structure but not necessarily the same data inside the child nodes and not the same order. How could I create a simple implementation for creating a third, temporary XML being the differential between the two first ones, using Microsoft's XML Diff .DLL ?

XML DIFF在MSDN上:

XML Diff on MSDN:

http://msdn.microsoft.com /en-us/library/aa302294.aspx

http://msdn.microsoft.com/en-us/library/aa302295.aspx

这两种不同的样本XML代码XML文件进行比较:

sample XML code of the two different XML files to compare:

<?xml version="1.0" encoding="utf-8" ?> 
<Stats Date="2011-01-01">
 <Player Rank="1">
  <Name>Sidney Crosby</Name> 
  <Team>PIT</Team> 
  <Pos>C</Pos> 
  <GP>39</GP> 
  <G>32</G> 
  <A>33</A> 
  <PlusMinus>20</PlusMinus> 
  <PIM>29</PIM> 
 </Player>
</Stats>

<?xml version="1.0" encoding="utf-8" ?> 
<Stats Date="2011-01-10">
 <Player Rank="1">
  <Name>Sidney Crosby</Name> 
  <Team>PIT</Team> 
  <Pos>C</Pos> 
  <GP>42</GP> 
  <G>35</G> 
  <A>34</A> 
  <PlusMinus>22</PlusMinus> 
  <PIM>30</PIM> 
 </Player>
</Stats>



结果通缉(两者之间的差)

Result wanted (difference between the two)

<?xml version="1.0" encoding="utf-8" ?> 
<Stats Date="2011-01-10">
 <Player Rank="1">
  <Name>Sidney Crosby</Name> 
  <Team>PIT</Team> 
  <Pos>C</Pos> 
  <GP>3</GP> 
  <G>3</G> 
  <A>1</A> 
  <PlusMinus>2</PlusMinus> 
  <PIM>1</PIM> 
 </Player>
</Stats>

在这种情况下,我可能会使用XSLT生成的XML转换差文件到一个整理HTML文件中,但我还没有。所有我想要做的是在第三XML来显示文件中每个节点的每一个数值,从GP子节点开始的差别。

In this case, I would probably use XSLT to convert the resulting XML "differential" file into a sorted HTML file, but I am not there yet. All I want to do is to display in the third XML file the difference of every numerical value of each nodes, starting from the "GP" child-node.

C#代码我至今:

private void CompareXml(string file1, string file2)
{

    XmlReader reader1 = XmlReader.Create(new StringReader(file1));
    XmlReader reader2 = XmlReader.Create(new StringReader(file2));

    string diffFile = StatsFile.XmlDiffFilename;
    StringBuilder differenceStringBuilder = new StringBuilder();

    FileStream fs = new FileStream(diffFile, FileMode.Create);
    XmlWriter diffGramWriter = XmlWriter.Create(fs);

    XmlDiff xmldiff = new XmlDiff(XmlDiffOptions.IgnoreChildOrder |
                            XmlDiffOptions.IgnoreNamespaces |
                            XmlDiffOptions.IgnorePrefixes);
    bool bIdentical = xmldiff.Compare(file1, file2, false, diffGramWriter);

    diffGramWriter.Close();

    // cleaning up after we are done with the xml diff file
    File.Delete(diffFile);
}   



}

}

这就是我有这么远,但结果是垃圾......注意,每一个玩家节点,前三个孩子的必须的的进行比较......我怎么能实现呢?

That's what I have so far, but the results is garbage... note that for each "Player" node, the first three childs have NOT to be compared... How can I implement this?

推荐答案

好吧......我最后用纯C#解决方案来比较两个XML文件,而无需使用XML的比较/补丁选择.dll和甚至无需使用XSL转换。我也将需要XSL在下一步转变不过,到XML转换成HTML转换观赏用途,但我想通仅仅使用的System.Xml和System.Xml.XPath的算法。

Okay... I finally opted with a pure C# solution to compare the two XML files, without using the XML Diff/Patch .dll and without even needing to use XSL transforms. I will be needing XSL transforms in the next step though, to convert the Xml into HTML for viewing purposes, but I have figured an algorithm using nothing but System.Xml and System.Xml.XPath.

下面是我的算法:

private void CompareXml(string file1, string file2)
{
    // Load the documents
    XmlDocument docXml1 = new XmlDocument();
    docXml1.Load(file1);
    XmlDocument docXml2 = new XmlDocument();
    docXml2.Load(file2);


    // Get a list of all player nodes
    XmlNodeList nodes1 = docXml1.SelectNodes("/Stats/Player");
    XmlNodeList nodes2 = docXml2.SelectNodes("/Stats/Player");

    // Define a single node
    XmlNode node1;
    XmlNode node2;

    // Get the root Xml element
    XmlElement root1 = docXml1.DocumentElement;
    XmlElement root2 = docXml2.DocumentElement;

    // Get a list of all player names
    XmlNodeList nameList1 = root1.GetElementsByTagName("Name");
    XmlNodeList nameList2 = root2.GetElementsByTagName("Name");

    // Get a list of all teams
    XmlNodeList teamList1 = root1.GetElementsByTagName("Team");
    XmlNodeList teamList2 = root2.GetElementsByTagName("Team");

    // Create an XmlWriterSettings object with the correct options. 
    XmlWriter writer = null;
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Indent = true;
    settings.IndentChars = ("  ");
    settings.OmitXmlDeclaration = false;

    // Create the XmlWriter object and write some content.
    writer = XmlWriter.Create(StatsFile.XmlDiffFilename, settings);
    writer.WriteStartElement("StatsDiff");


    // The compare algorithm
    bool match = false;
    int j = 0;

    try 
    {
        // the list has 500 players
        for (int i = 0; i < 500; i++)
        {
            while (j < 500 && match == false)
            {
                // There is a match if the player name and team are the same in both lists
                if (nameList1.Item(i).InnerText == nameList2.Item(j).InnerText)
                {
                    if (teamList1.Item(i).InnerText == teamList2.Item(j).InnerText)
                    {
                        match = true;
                        node1 = nodes1.Item(i);
                        node2 = nodes2.Item(j);
                        // Call to the calculator and Xml writer
                        this.CalculateDifferential(node1, node2, writer);
                        j = 0;
                    }
                }
                else
                {
                    j++;
                }
            }
            match = false;

        }
        // end Xml document
        writer.WriteEndElement();
        writer.Flush();
    }
    finally
    {
        if (writer != null)
            writer.Close();
    }
}



XML结果:

XML Results:

<?xml version="1.0" encoding="utf-8"?>
<StatsDiff>    
  <Player Rank="1">
    <Name>Sidney Crosby</Name>
    <Team>PIT</Team>
    <Pos>C</Pos>
    <GP>0</GP>
    <G>0</G>
    <A>0</A>
    <Points>0</Points>
    <PlusMinus>0</PlusMinus>
    <PIM>0</PIM>
    <PP>0</PP>
    <SH>0</SH>
    <GW>0</GW>
    <OT>0</OT>
    <Shots>0</Shots>
    <ShotPctg>0</ShotPctg>
    <ShiftsPerGame>0</ShiftsPerGame>
    <FOWinPctg>0</FOWinPctg>
  </Player>

  <Player Rank="2">
    <Name>Steven Stamkos</Name>
    <Team>TBL</Team>
    <Pos>C</Pos>
    <GP>1</GP>
    <G>0</G>
    <A>0</A>
    <Points>0</Points>
    <PlusMinus>0</PlusMinus>
    <PIM>2</PIM>
    <PP>0</PP>
    <SH>0</SH>
    <GW>0</GW>
    <OT>0</OT>
    <Shots>4</Shots>
    <ShotPctg>-0,6000004</ShotPctg>
    <ShiftsPerGame>-0,09999847</ShiftsPerGame>
    <FOWinPctg>0,09999847</FOWinPctg>
  </Player>
[...]
</StatsDiff>



我也未能幸免,以示对CalculateDifferential()方法的实现,这是非常奇怪的,但它是快捷,高效。这样我可以得到的结果要在不使用任何其它的参考,但严格的最低限度,而不必使用XSL ...

I have spared to show the implementation for the CalculateDifferential() method, it is rather cryptic but it is fast and efficient. This way I could obtain the results wanted without using any other reference but the strict minimum, without having to use XSL...

这篇关于比较两个XML文件和放大器;产生第三位的xmldiff在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆