我试图在两个XML文档上执行leftOuterJoin,但是我当前使用的方式似乎从fileone返回一些奇怪的重复部分(在下面的代码中解释)。我尝试了很多方法,但无法弄清楚如何做到这一点。有人可以帮忙解决问题吗?提前谢谢了!
fileone:
<fileone>
<Book BookID="dog"> Dog </Book>
<Book BookID="cat"> Cat </Book>
</fileone>
FileTwo传送:
<filetwo>
<Edition BID="cat" OrderID="100"> about cat</Edition>
<Edition BID="cat" OrderID="200">more about cat</Edition>
</RightSeq>
我正在寻找的是(在bookID = BID上留下外部联接):
<item>
<Book BookID="cat"> Dog </Book>
</item>
<item>
<Book BookID="cat"> Cat </Book>
<Edition BID="cat" OrderID="100"> about cat</Edition>
</item>
<item>
<Book BookID="cat"> Cat </Book>
<Edition BID="cat" OrderID="200"> more cat</Edition>
</item>
我的(错误)代码:
var result = from a in fileone.Descendants()
join b in secondxdoc.Descendants()
on (string)a.Attribute("BookID") equal (string)b.Attribute("BID") into inners
from ele in inners.DefaultIfEmpty()
select new XElement("item", new XElement(a), ele == null ? null : new XElement(ele));
var output = new XElement("LeftOuterJoin", result);
}
目前错误的结果:
<item>
<fileone>
<Book BookID="dog"> Dog </Book> // this entire <fileone> bit is unwanted
<Book BookID="cat"> Cat </Book> //I don't know what I've done wrong
</fileone>
</item>
<item>
<Book BookID="cat"> Dog </Book>
</item>
<item>
<Book BookID="cat"> Cat </Book>
<Edition BID="cat" OrderID="100"> about cat</Edition>
</item>
<item>
<Book BookID="cat"> Cat </Book>
<Edition BID="cat" OrderID="200"> more cat</Edition>
</item>
答案 0 :(得分:2)
不需要的第一个null
元素是将根元素public class Foo
{
private int[ , ] Bar; // Bar will be null until initialized
public Foo(int a, int b)
{
Bar = new int[a, b];
}
}
与第二个文件的后代连接起来的结果。如果您想跳过根元素,请将<item>
替换为<fileone>
:
fileone.Descendants()
<强> Dotnetfiddle Demo
强>
答案 1 :(得分:0)
我没有使用传统的linq就得到了结果。如果fileone在filetwo中没有匹配的项目,则联接不会给出结果。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input1 =
"<fileone>" +
"<Book BookID=\"dog\"> Dog </Book>" +
"<Book BookID=\"cat\"> Cat </Book>" +
"</fileone>";
XDocument fileone = XDocument.Parse(input1);
string input2 =
"<filetwo>" +
"<Edition BID=\"cat\" OrderID=\"100\"> about cat</Edition>" +
"<Edition BID=\"cat\" OrderID=\"200\">more about cat</Edition>" +
"</filetwo>";
XDocument secondxdoc = XDocument.Parse(input2);
//<item>
// <Book BookID="cat"> Dog </Book>
//</item>
//<item>
// <Book BookID="cat"> Cat </Book>
// <Edition BID="cat" OrderID="100"> about cat</Edition>
//</item>
//<item>
// <Book BookID="cat"> Cat </Book>
// <Edition BID="cat" OrderID="200"> more cat</Edition>
//</item>
XElement output = new XElement("Root");
foreach (XElement item in fileone.Descendants("Book"))
{
string bookId = item.Attribute("BookID").Value;
List<XElement> bookTwoItems = secondxdoc.Descendants("Edition").Where(x => x.Attribute("BID").Value == bookId).ToList();
if (bookTwoItems.Count == 0)
{
XElement newItem = new XElement("item");
output.Add(newItem);
newItem.Add(item);
}
else
{
foreach (XElement bookTwoItem in bookTwoItems)
{
XElement newItem = new XElement("item");
output.Add(newItem);
newItem.Add(item);
newItem.Add(bookTwoItem);
}
}
}
}
}
}
&#13;
使用Left Outer Join
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input1 =
"<fileone>" +
"<Book BookID=\"dog\"> Dog </Book>" +
"<Book BookID=\"cat\"> Cat </Book>" +
"</fileone>";
XDocument fileone = XDocument.Parse(input1);
string input2 =
"<filetwo>" +
"<Edition BID=\"cat\" OrderID=\"100\"> about cat</Edition>" +
"<Edition BID=\"cat\" OrderID=\"200\">more about cat</Edition>" +
"</filetwo>";
XDocument secondxdoc = XDocument.Parse(input2);
//<item>
// <Book BookID="cat"> Dog </Book>
//</item>
//<item>
// <Book BookID="cat"> Cat </Book>
// <Edition BID="cat" OrderID="100"> about cat</Edition>
//</item>
//<item>
// <Book BookID="cat"> Cat </Book>
// <Edition BID="cat" OrderID="200"> more cat</Edition>
//</item>
var results = (from one in fileone.Descendants("Book")
join two in secondxdoc.Descendants("Edition") on one.Attribute("BookID").Value equals two.Attribute("BID").Value into inners
from two in inners.DefaultIfEmpty()
select new { fileone = one, filetwo = two == null ? null : two }).ToList();
XElement output = new XElement("Root");
foreach (var item in results)
{
XElement newItem = new XElement("item");
output.Add(newItem);
newItem.Add(item.fileone);
if (item.filetwo != null)
{
newItem.Add(item.filetwo);
}
}
}
}
}
或者这个方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input1 =
"<fileone>" +
"<Book BookID=\"dog\"> Dog </Book>" +
"<Book BookID=\"cat\"> Cat </Book>" +
"</fileone>";
XDocument fileone = XDocument.Parse(input1);
string input2 =
"<filetwo>" +
"<Edition BID=\"cat\" OrderID=\"100\"> about cat</Edition>" +
"<Edition BID=\"cat\" OrderID=\"200\">more about cat</Edition>" +
"</filetwo>";
XDocument secondxdoc = XDocument.Parse(input2);
//<item>
// <Book BookID="cat"> Dog </Book>
//</item>
//<item>
// <Book BookID="cat"> Cat </Book>
// <Edition BID="cat" OrderID="100"> about cat</Edition>
//</item>
//<item>
// <Book BookID="cat"> Cat </Book>
// <Edition BID="cat" OrderID="200"> more cat</Edition>
//</item>
XElement output = new XElement("Root");
var results = (from one in fileone.Descendants("Book")
join two in secondxdoc.Descendants("Edition") on one.Attribute("BookID").Value equals two.Attribute("BID").Value into inners
from two in inners.DefaultIfEmpty()
select new { fileone = one, filetwo = two == null ? null : two })
.Select(x => x.filetwo == null ? new XElement("item", x.fileone) : new XElement("item", new object[] { x.fileone, x.filetwo }));
foreach (var item in results)
{
output.Add(item);
}
}
}
}