代码之家  ›  专栏  ›  技术社区  ›  Will Eddins ianpoley

将XML文件与更改列表合并

  •  0
  • Will Eddins ianpoley  · 技术社区  · 16 年前

    主设置文件:

    <?xml version="1.0"?>
    <preset>
      <var id="9" opt="0" val="6666666"/>
      <var id="9" opt="1" val="10000000"/>
      <var id="9" opt="2" val="10000000"/>
      <var id="9" opt="3" val="10000000"/>
      <var id="9" opt="4" val="0"/>
      <var id="10" opt="0" val="4"/>
      <var id="11" opt="0" val="0"/>
      <var id="15" opt="0" val="75"/>
      <var id="22" opt="0" val="0,0,127,516" type="rect(l,t,r,b)"/>
      <var id="23" opt="0" val="27,18,92,66" type="rect(l,t,r,b)"/>
      <var id="24" opt="0" val="320"/>
      ... Skip 300 lines ...
    </preset>
    

    <?xml version="1.0"?>
    <preset>
      <var id="15" opt="0" val="425"/>
      <var id="22" opt="0" val="0,0,127,776" type="rect(l,t,r,b)"/>
      <var id="26" opt="0" val="147"/>
      <var id="27" opt="0" val="147"/>
      <var id="109" opt="1" val="7"/>
      <var id="126" opt="0" val="6,85,85,59" type="crv(t,m,b,vm)"/>
      <var id="157" opt="0" val="1"/>
      ... Skip 10 lines ...
    </preset>
    

    id="#" opt="#" id="15" opt="0" 将从75变为425。

    XmlDocument

    4 回复  |  直到 16 年前
        1
  •  3
  •   Jeff Hillman    16 年前

    如果文件变得非常大,这将非常低效,但这就是使用XmlDocuments的方法:

    XmlDocument main = new XmlDocument();
    main.Load( "main.xml" );
    
    XmlDocument changes = new XmlDocument();
    changes.Load( "changes.xml" );
    
    foreach ( XmlNode mainNode in main.SelectNodes( "preset/var" ) )
    {
        string mainId = mainNode.Attributes[ "id" ].Value;
        string mainOpt = mainNode.Attributes[ "opt" ].Value;
    
        foreach ( XmlNode changeNode in changes.SelectNodes( "preset/var" ) )
        {
            if ( mainId == changeNode.Attributes[ "id" ].Value &&
                mainOpt == changeNode.Attributes[ "opt" ].Value )
            {
                mainNode.Attributes[ "val" ].Value = changeNode.Attributes[ "val" ].Value;
            }
        }
    }
    
    // save the updated main document
    main.Save( "updated_main.xml" );
    
        2
  •  2
  •   Murph    16 年前

    void Main()
    {
        XDocument settingsXML = XDocument.Load(@"c:\temp\settings.xml");
        XDocument updateXML = XDocument.Load(@"c:\temp\updates.xml");
    
        Console.WriteLine("Processing");
    
        // Loop through the updates
        foreach(XElement update in updateXML.Element("preset").Elements("var"))
        {    
            // Find the element to update    
            XElement settingsElement = 
                (from s in settingsXML.Element("preset").Elements("var")
                 where s.Attribute("id").Value == update.Attribute("id").Value &&
                       s.Attribute("opt").Value == update.Attribute("opt").Value
                 select s).FirstOrDefault();    
            if (settingsElement != null)    
            {      
                settingsElement.Attribute("val").Value = update.Attribute("val").Value;    
                // Handling for additional attributes here
            }    
            else    
            {   
                // not found handling    
                Console.WriteLine("Not found {0},{1}", update.Attribute("id").Value,
                                                       update.Attribute("opt").Value);
            }
        }
        Console.WriteLine("Saving");
        settingsXML.Save(@"c:\temp\updatedSettings.xml");
        Console.WriteLine("Finis!");
    }
    

    添加使用子句作为练习:)

    here 但它在VB中具有更多的XML功能。

    我还认为,通过将两组XML数据连接起来进行查询,生成一个包含XElement及其需要更新的值(或多个值)的动态类型列表,可能会做一些非常优雅的事情。但我已经花了足够的时间和这个玩了一个晚上了

        3
  •  2
  •   Brian ONeil    16 年前

    在Linq-to-XML中使用连接将文档关联在一起的示例。首先,我选择在两个属性上匹配的元素,然后将它们更新为更改文件中的新值。

    XDocument main = XDocument.Load("XMLFile1.xml");
    XDocument changes = XDocument.Load("XMLFile2.xml");
    
    var merge = from entry in main.Descendants("preset").Descendants("var")
                join change in changes.Descendants("preset").Descendants("var")
                on 
                   new {a=entry.Attribute("id").Value, b=entry.Attribute("opt").Value}
                equals 
                   new {a=change.Attribute("id").Value, b=change.Attribute("opt").Value}
                select new
                {
                   Element = entry,
                   newValue = change.Attribute("val").Value                       
                };
    
                merge.ToList().ForEach(i => i.Element.Attribute("val").Value = i.newValue);
    
                main.Save("XMLFile3.xml");
    
        4
  •  0
  •   Guesty    16 年前

    不管怎样,XmlDocument方法类似于:

    1. 遍历更改文件XmlDocument对象中的var节点列表,并在找到时对原始文件XmlDocument对象运行xpath查询,以搜索具有匹配id的节点(使用原始文件XmlDocument物体上的SelectSingleNode()方法)。在节点中编辑需要编辑的属性。