XElement - 将多个元素合并为一个

问题描述

我无法将两个 XML 合并为一个

一个 XML:

<?xml version="1.0" encoding="utf-8"?>
<SalesOrderHeader>
  <SOFields>
    <CompanyName>company</CompanyName>
    <joinKey>c9e60279-6759-eb11-a2e4-00155d0a9c55</joinKey>
    <SalesId>SO100001</SalesId>
  </SOFields>
</SalesOrderHeader>

第二个 XML:

<?xml version="1.0" encoding="utf-8"?>
<SalesOrderLines>
  <SOL>
    <CompanyName>company</CompanyName>
    <SOLUniqueKey>fe695341-6959-eb11-a2e4-00155d0a9c55</SOLUniqueKey>
    <ItemId>12345</ItemId>
    <ItemName>ItemName1</ItemName>
    <SalesOrderJoinKey>c9e60279-6759-eb11-a2e4-00155d0a9c55</SalesOrderJoinKey>
    <SalesAmount>100.0000</SalesAmount>
    <SalesPrice>20.0000</SalesPrice>
  </SOL>
    <SOL>
    <CompanyName>company</CompanyName>
    <SOLUniqueKey>ff695342-6959-eb11-a2e4-00155d0a9c55</SOLUniqueKey>
    <ItemId>34597</ItemId>
    <ItemName>ItemName2</ItemName>
    <SalesOrderJoinKey>c9e60279-6759-eb11-a2e4-00155d0a9c55</SalesOrderJoinKey>
    <SalesAmount>5.0000</SalesAmount>
    <SalesPrice>10.0000</SalesPrice>
  </SOL>
    <SOL>
    <CompanyName>company</CompanyName>
    <SOLUniqueKey>fz695343-6959-eb11-a2e4-00155d0a9c55</SOLUniqueKey>
    <ItemId>65874</ItemId>
    <ItemName>ItemName3</ItemName>
    <SalesOrderJoinKey>c9e60279-6759-eb11-a2e4-00155d0a9c55</SalesOrderJoinKey>
    <SalesAmount>10.0000</SalesAmount>
    <SalesPrice>24.0000</SalesPrice>
  </SOL>
</SalesOrderLines>

这两个 XML 文件是由 XElement 组成的。 我正在尝试像这样加入这两个文件

var newSOH = new XElement("SalesOrder",from c in xmlElement.Element("SalesOrderHeader").Elements("SOFields")
                    join o in xmlElementSOL.Element("SalesOrderLines").Elements("SOL")
                           on (string)c.Element("joinKey") equals
                              (string)o.Element("SalesOrderJoinKey")

连接元素是 SalesOrderHeader 上的 joinKey 和 SOL 上的 SalesOrderJoinKey

但是,此连接导致“未将对象引用设置为对象的实例。”

最终结果是第二个 XML (SalesOrderLInes) 文件中的所有元素都将位于一个销售订单标题下,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<SalesOrder>
<SalesOrderHeader>
  <SOFields>
    <CompanyName>company</CompanyName>
    <joinKey>c9e60279-6759-eb11-a2e4-00155d0a9c55</joinKey>
    <SalesId>SO100001</SalesId>
  </SOFields>
 </SalesOrderHeader>
<SalesOrderLines>
    <SOL>
    <CompanyName>company</CompanyName>
    <SOLUniqueKey>fe695341-6959-eb11-a2e4-00155d0a9c55</SOLUniqueKey>
    <ItemId>12345</ItemId>
    <ItemName>ItemName1</ItemName>
    <SalesOrderJoinKey>c9e60279-6759-eb11-a2e4-00155d0a9c55</SalesOrderJoinKey>
    <SalesAmount>100.0000</SalesAmount>
    <SalesPrice>20.0000</SalesPrice>
  </SOL>
    <SOL>
    <CompanyName>company</CompanyName>
    <SOLUniqueKey>ff695342-6959-eb11-a2e4-00155d0a9c55</SOLUniqueKey>
    <ItemId>34597</ItemId>
    <ItemName>ItemName2</ItemName>
    <SalesOrderJoinKey>c9e60279-6759-eb11-a2e4-00155d0a9c55</SalesOrderJoinKey>
    <SalesAmount>5.0000</SalesAmount>
    <SalesPrice>10.0000</SalesPrice>
  </SOL>
    <SOL>
    <CompanyName>company</CompanyName>
    <SOLUniqueKey>fz695343-6959-eb11-a2e4-00155d0a9c55</SOLUniqueKey>
    <ItemId>65874</ItemId>
    <ItemName>ItemName3</ItemName>
    <SalesOrderJoinKey>c9e60279-6759-eb11-a2e4-00155d0a9c55</SalesOrderJoinKey>
    <SalesAmount>10.0000</SalesAmount>
    <SalesPrice>24.0000</SalesPrice>
  </SOL>
</SalesOrderLines>
</SalesOrder>

我曾尝试遵循此示例 https://docs.microsoft.com/en-us/dotnet/standard/linq/join-two-collections,但根据我在其他帖子中阅读的内容,此方法对我不起作用。

感谢您提供的任何建议。

解决方法

鉴于您已将每个 XML 解析为 XElement,它已经引用了根元素,因此您无需再在查询中提及根元素:

var newSOH = new XElement("SalesOrder",from c in xmlElement.Elements("SOFields")
        join o in xmlElementSOL.Elements("SOL")
                on (string)c.Element("joinKey") equals
                    (string)o.Element("SalesOrderJoinKey")
        select new List<XElement>(){
            new XElement("SalesOrderHeader",c),new XElement("SalesOrderLines",o)
        });


System.Console.WriteLine(newSOH.ToString());

dotnetfiddle demo