问题描述
|
XML:
<root>
<item>
<href>http://myurl</href>
</item>
<item>
<href>http://myurl2</href>
</item>
</root>
XML数据存储在数据库表中。
我可以建立一个Linq查询来选择行,提取XML,然后例如提取所有href标签吗?最终结果将是所有选定行的所有URL的列表。
这是我的尝试,但没有给我我想要的东西-这将是所有选定用户的所有href的列表。我只得到一个空的IEnumerations列表。
var all = from bm in MYTABLE
select new { name=bm.SPP_USER_ID,xml=(string) bm.SPP_BOOKMARKS_XML};
var docs = from x in all
select XDocument.Parse(x.xml);
var href = from h in docs
select h.Descendants(\"href\");
解
有两个问题。
-我猜只有在实际需要结果时才执行查询。当我从sql进行到XML查询时,结果查询变成了sql和XML的混合,因此无法执行。我的解决方案是通过将SQL查询转换为结果列表来强制结果。这将linq-sql与linq-xml分开了。
var docs = from x in all
select XDocument.Parse(x.xml);
var docs2 = docs.ToList(); // force result
-第二个问题是我忘记将名称空间添加到XML查询中。一旦我做到了,我得到了所需的结果
XNamespace ns = \"http://acme/bookmarks\";
var href = from h in docs2
select h.Descendants(ns + \"href\");
感谢你的帮助!
解决方法
这是我尝试过的几件事。
设置:我用表MYTABLE创建了一个数据库,该表包含2列。列1(SPP_USER_ID)是varchar(255),列2(SPP_BOOKMARKS_XML)是xml数据类型。我添加了2行,以反映mellamokb使用的行。我创建了LINQ to SQL设计图并将其拖到该表中。我的应用程序只是一个控制台应用程序,可将LINQ加载到SQL数据上下文中,然后调用您的命令。
我直接针对数据表查询,如下所示:
var all = from bm in context.MYTABLEs
select new { name = bm.SPP_USER_ID,xml = (string)bm.SPP_BOOKMARKS_XML };
var docs = from x in all
select XDocument.Parse(x.xml);
var href = from h in docs
select h.Descendants(\"href\");
结果是IEnumerables的集合。即对于数据库中的每一行,我都有一个IEnumerable,其中包含所有\“ href \”后代。因此,在这种情况下,我得到了两个结果;第一个结果是包含2个元素的IEnumerable,第二个结果是包含1个元素的IEnumerable。从您的描述看来,这至少接近您想要的。但是,可能由于查询的结构方式而看不到期望的结果。
请注意,有时很难使Visual Studio真正向您显示这样的查询结果。我发现我经常不得不“监视”该项目两次,然后才开始触发结果枚举。
我试图复制您的OP中编写的代码,如下所示:
var MYTABLE = (from bm in context.MYTABLEs select bm).ToList();
var all = from bm in MYTABLE
select new { name = bm.SPP_USER_ID,xml = (string)bm.SPP_BOOKMARKS_XML };
var docs = from x in all
select XDocument.Parse(x.xml);
var href = from h in docs
select h.Descendants(\"href\");
当我这样做时,它导致\“ xml \”值被废弃,因为它已经是一个XDocument(?),因此将其强制转换为字符串会导致所有标记被剥离。因此,接下来的两个语句由于XML解析异常而失败。
, 这是一个使用您的代码和a6ѭ硬编码内容的代码段,它完美地工作(已通过LinqPad验证)。也许您的数据库表或MYTABLE
不包含您认为的内容?您可以查看all
的结果吗?
var MYTABLE = new [] {
new {
SPP_USER_ID = \"XML-SNIPPET-1\",SPP_BOOKMARKS_XML = @\"
<root>
<item>
<href>http://myurl</href>
</item>
<item>
<href>http://myurl2</href>
</item>
</root>
\",},new {
SPP_USER_ID = \"XML-SNIPPET-2\",SPP_BOOKMARKS_XML = @\"
<root>
<item>
<href>http://google.com</href>
</item>
</root>
\",}
};
var all = from bm in MYTABLE
select new { name=bm.SPP_USER_ID,xml=(string) bm.SPP_BOOKMARKS_XML};
var docs = from x in all
select XDocument.Parse(x.xml);
var href = from h in docs
select h.Descendants(\"href\");
foreach (var h in href.SelectMany(h => h))
{
Console.WriteLine(h);
}
输出:
<href>http://myurl</href>
<href>http://myurl2</href>
<href>http://google.com</href>
希望这可以帮助!