XElement - 将多个元素合并到一个下

Posted

技术标签:

【中文标题】XElement - 将多个元素合并到一个下【英文标题】:XElement - joining multiple elements under one 【发布时间】:2021-06-01 22:57:03 【问题描述】:

我无法将两个 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 但从我在其他帖子中阅读的内容来看,此方法对我不起作用。

感谢您提供的任何建议。

【问题讨论】:

【参考方案1】:

鉴于您已将每个 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

【讨论】:

@Ruslan 这种方法有什么问题吗?

以上是关于XElement - 将多个元素合并到一个下的主要内容,如果未能解决你的问题,请参考以下文章

使用 XElement 创建带前缀的 XML 元素

从具有多个命名空间的 XElement 中获取元素

如何将子元素作为解码字符串添加到 XElement?

XElement 会自动将 xmlns="" 添加到自身

将 XElement 添加到特定位置的另一个 XElement

将部分 XML 字符串解析为 XElement 列表