用于 XML 的 C# LINQ Left Outer Join 无法正常工作

Posted

技术标签:

【中文标题】用于 XML 的 C# LINQ Left Outer Join 无法正常工作【英文标题】:C# LINQ Left Outer Join for XML doesn't work properly 【发布时间】:2015-10-31 19:15:42 【问题描述】:

我正在尝试为两个 XML 执行 Left Outer Join 并获取另一个 XML(不是集合!)作为输出,但 LINQ 的查询“进入”似乎只提取值,但不是具有所有原始标签和属性的完整元素。

我的 xml1 看起来像这样:

<tag>
  <abc id="zxy">tiger</abc>
  <abc id="zzz">rabbit</abc>
</tag>

我的xml2

<tag>
  <aaa attr1="1" attr2="zzz">value1</aaa>
  <aaa attr1="2" attr2="zxc">value2</aaa>
</tag>

我的 C# 代码:

var que= from first in xml1
         join second in xml2
         on (string)first.Attribute(attr1) equals (string)second.Attribute(attr2) into temp
         from tmpL in temp.DefaultIfEmpty()
         orderby (string)first.Attribute(attr1)//, (string)tmpL.Attribute(attr2) -- this one isn't working because it's not an element
         select new XElement("child", first, tmpL == null ? String.Empty : (string)tmpL);

var final= new XDocument(new XElement("parent", que));

这就是我使用该代码加入上述两个 XML 的结果:

<parent>
  <child>
    <abc id="zxy">tiger</abc>value1</child>
  <child>
    <abc id="zzz">rabbit</abc>value2</child>
</parent>

如您所见,这是一个无效的 XML,其 value1 和 value2 粘在兄弟元素上,而它们应该被包装在它们自己的原始标签中(具有它们的原始属性):&lt;aaa attr1="1" attr2="zzz"&gt;value1&lt;/aaa&gt;&lt;aaa attr1="2" attr2="zxc"&gt;value2&lt;/aaa&gt; 对应。

因此我不能在它们上使用 .Attribute() 和其他东西。 此外,我不能只在新创建的元素中插入这些值,因为我需要 xml2 中原始元素的属性。

您能帮我获取以下 XML 吗?

<parent>
  <child>
    <abc id="zxy">tiger</abc>
    <aaa attr1="1" attr2="zzz">value1</aaa>
  </child>
  <child>
    <abc id="zzz">rabbit</abc>
    <aaa attr1="2" attr2="zxc">value2</aaa>
  </child>
</parent>

【问题讨论】:

【参考方案1】:

"..但是 LINQ 的查询 'into' 似乎只提取值,而不是提取具有所有原始标签和属性的完整元素"

您实际上得到了XElements,但随后它被显式转换为string,这导致仅保留字符串值,在这里:

select new XElement("child", first, tmpL == null ? String.Empty : (string)tmpL);

当您不希望任何内容成为新创建的 child 元素的子元素时,删除强制转换并简单地传递 null 而不是 String.Empty

select new XElement("child", first, tmpL == null ? null : tmpL);

或者简单地传递tmpL,不管它是否是null,这会产生一个等效但更清晰的语句:

select new XElement("child", first, tmpL);

【讨论】:

非常感谢!有效!唯一剩下的就是 orderby,我在最初的评论中指出:orderby (string)first.Attribute(attr1)//, (string)tmpL.Attribute(attr2) -- this one isn't working because it's not an element。我在tmpL.Attribute(attr2)之前删除了string,但它仍然说它不是对象的实例有没有办法使用它来订购?

以上是关于用于 XML 的 C# LINQ Left Outer Join 无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

C# linq to Xml(复习用)

C#中的Linq to Xml详解

使用 C# LINQ 解析 XML 文档

C# Linq 计算具有特定值的 XML 段

在 C# 中使用 LINQ 解析 XML

使用 Linq 使用 C# 更新 XML