合并两个XML文件,具有一对多关系C#的文件

时间:2014-10-16 05:32:11

标签: c# .net xml

我有两个XML文件,  1.合同

<?xml version="1.0" encoding="UTF-8"?>
<File>
   <Contract>
      <ContractNo>1</ContractNo>
   </Contract>
   <Contract>
      <ContractNo>2</ContractNo>
   </Contract>
</File>

2。资产

<?xml version="1.0" encoding="UTF-8"?>
<File>
   <Asset>
      <ContractNo>1</ContractNo>
      <SomeData>XXXX</SomeData>
      <SomeData2>XXXX</SomeData2>
   </Asset>
   <Asset>
      <ContractNo>1</ContractNo>
      <SomeData>YYYY</SomeData>
      <SomeData2>YYYY</SomeData2>
   </Asset>
   <Asset>
      <ContractNo>2</ContractNo>
      <SomeData>ZZZZ</SomeData>
      <SomeData>ZZZZ</SomeData>
   </Asset>
</File>

合同可能包含一项或多项资产。 XML文件由合同号映射。我要合并这两个文件 创建以下xml

<?xml version="1.0" encoding="UTF-8"?>
<File>
   <Contract>
      <ContractNo>1</ContractNo>
      <Asset>
         <SomeData>XXXX</SomeData>
         <SomeData2>XXXX</SomeData2>
      </Asset>
      <Asset>
         <SomeData>YYYY</SomeData>
         <SomeData2>YYYY</SomeData2>
      </Asset>
   </Contract>
   <Contract>
      <ContractNo>2</ContractNo>
      <Asset>
         <SomeData>ZZZZ</SomeData>
         <SomeData2>ZZZZ</SomeData2>
      </Asset>
   </Contract>
</File>

我的方法是迭代合同xml的每个合同并找到合同号,然后迭代资产xml并找到上述合同的资产节点和 将它们合并到合同xml

XmlNodeList contractsNodeList = contractsDocument.GetElementsByTagName("Contract");
string contractNumber;
foreach (XmlNode contractNode in contractsNodeList)
{
    //get the contract number
    contractNumber = contractNode.SelectSingleNode("ContractNo").InnerText;

    if (!String.IsNullOrEmpty(contractNumber))
    {
        XmlNodeList assetsNodeList = assetsDocument.GetElementsByTagName("Asset");
        foreach (XmlNode assetNode in assetsNodeList)
        {
            //checking whether the current asset node has the current contract number 
            if (assetNode.ChildNodes[0].InnerText == contractNumber)
            {
                //remove the contract number of the asset node
                assetNode.RemoveChild(assetNode.ChildNodes[0]);
                //append the asset element to the contract xml
                contractNode.AppendChild(contractNode.OwnerDocument.ImportNode(assetNode, true));
            }
        }
    }
}

此代码可以生成并生成所需的xml。但效率不高。我在使用XML方面没有多少经验。请让我知道任何其他方式 做这个。谢谢!

1 个答案:

答案 0 :(得分:2)

我会亲自阅读资产,然后填充ILookup<int, XElement>并删除ContractNo元素(因为它在LINQ to XML中稍微简单一些)。然后阅读合同,从字典中填充资产。类似的东西:

XDocument assets = XDocument.Load("assets.xml");
var lookup = assets.Root.Elements("Asset")
                        .ToLookup(x => (int) x.Element("ContractNo"));
assets.Root.Elements("Asset").Elements("ContractNo").Remove();

XDocument contracts = XDocument.Load("contracts.xml");
foreach (var contract in contracts.Root.Elements("Contract").ToList())
{
    var id = (int) contract.Element("ContractNo");
    contract.Add(lookup[id]);
}
contracts.Save("results.xml");

请注意,这并不能检测到没有任何资产的合同 - 它们只会保持不变。

所有这些都可以在&#34; old&#34; XmlDocument API,但LINQ to XML确实使它更简单。