C# 在C中使用Ling解析xml#
嗨,我有一个Xml文档,使用C# 在C中使用Ling解析xml#,c#,xml,linq,C#,Xml,Linq,嗨,我有一个Xml文档,使用 var doc = XDocument.Load(reader); xml看起来像这样 <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE document SYSTEM 'xmlschemas/some.dtd'> <document xmlns='http://www.abcd.com/dxl' version='9.0' someversion='1.0' re
var doc = XDocument.Load(reader);
xml看起来像这样
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE document SYSTEM 'xmlschemas/some.dtd'>
<document xmlns='http://www.abcd.com/dxl' version='9.0' someversion='1.0'
replicaid='0xxxxDB' form='Test'>
<item name='From'>
<text>John Doe</text>
</item>
<item name='SentTo'>
<text>Another John Doe</text>
</item>
<item name='ModTime'>
<datetime dst='true'>20180129T114649,22-02</datetime>
</item>
<item name='Body' sign='true' seal='true'>
<attachmentref name='some.pdf' displayname='some.pdf'>
<picture height='34px' width='342px'>
<notesbitmap>
lQAmAAAAAAAAAAAAAAABAAAAAAAAAFYBI
</notesbitmap>
</picture>
我想将名称属性为“From”和“SentTo”的项目标记作为目标,我可能不想将其他标记作为目标。
提前感谢。我可能会使用我需要的属性和属性创建类项,并将XML反序列化到其中,稍后,我将使用LINQ过滤值。请看这里:
我希望这会有所帮助。我可能会使用我需要的属性和属性创建类项,并将XML反序列化到其中,稍后,我将使用LINQ过滤值。请看这里:
我希望这能有所帮助。您不想使用HtmlAgilityPack进行XML解析。但是,如果您明白这可能是一个问题,但仍然接受此决定,那么您可以执行以下操作:
var relevantItems = doc.DocumentNode
.Descendants("item")
.Select(x => new
{
Item = x,
ItemName = x.Attributes.Contains("name") ? x.Attributes["name"].Value : null
})
.Where(x => x.ItemName == "From" || x.ItemName == "SentTo")
.Select(x => x.Item)
.ToList();
您不想使用HtmlAgilityPack进行XML解析。但是,如果您明白这可能是一个问题,但仍然接受此决定,那么您可以执行以下操作:
var relevantItems = doc.DocumentNode
.Descendants("item")
.Select(x => new
{
Item = x,
ItemName = x.Attributes.Contains("name") ? x.Attributes["name"].Value : null
})
.Where(x => x.ItemName == "From" || x.ItemName == "SentTo")
.Select(x => x.Item)
.ToList();
问题的一部分是您正在查找没有名称空间的元素,但您的文档确实指定了默认名称空间。幸运的是,LINQtoXML使名称空间处理变得简单 您还使用了
子体
来尝试查找一个属性的值(我相信),而这不是它的工作方式
下面是一个可行的示例—假设您的目标是从每个
元素中获取
内容,该元素的名称属性为SentTo
:
using System;
using System.Linq;
using System.Xml.Linq;
class Test
{
static void Main()
{
var doc = XDocument.Load("test.xml");
XNamespace ns = "http://www.abcd.com/dxl";
var sentToValues = doc.Root
.Elements(ns + "item")
.Where(item => (string) item.Attribute("name") == "SentTo")
.Select(item => (string) item.Element(ns + "text"))
.ToList();
foreach (var value in sentToValues)
{
Console.WriteLine(value);
}
}
}
问题的一部分是您正在查找没有名称空间的元素,但您的文档确实指定了默认名称空间。幸运的是,LINQtoXML使名称空间处理变得简单
您还使用了子体
来尝试查找一个属性的值(我相信),而这不是它的工作方式
下面是一个可行的示例—假设您的目标是从每个
元素中获取
内容,该元素的名称属性为SentTo
:
using System;
using System.Linq;
using System.Xml.Linq;
class Test
{
static void Main()
{
var doc = XDocument.Load("test.xml");
XNamespace ns = "http://www.abcd.com/dxl";
var sentToValues = doc.Root
.Elements(ns + "item")
.Where(item => (string) item.Attribute("name") == "SentTo")
.Select(item => (string) item.Element(ns + "text"))
.ToList();
foreach (var value in sentToValues)
{
Console.WriteLine(value);
}
}
}
您的xml包含命名空间
。因此,您也必须在代码中读取该名称空间
XDocument doc = XDocument.Load(@"XMLFile1.xml");
XNamespace ns = doc.Root.GetDefaultNamespace();
var text = doc.Descendants(ns + "item")
.Single(c => c.Attribute("name").Value == "SentTo")
.Elements(ns + "text")
.Select(item => (string)item)
.FirstOrDefault();
输出:
因此,如果您想要获取多个name
attributetext
节点,那么
//This is sample string of array
string[] strArray = new string[2] { "From", "SentTo" };
var list = doc.Descendants(ns + "item")
.Where(c => strArray == null || strArray.Any(x => x.Contains(c.Attribute("name").Value)))
.Elements(ns + "text")
.Select(item => (string)item)
.ToList();
输出:
您的xml包含名称空间
。因此,您也必须在代码中读取该名称空间
XDocument doc = XDocument.Load(@"XMLFile1.xml");
XNamespace ns = doc.Root.GetDefaultNamespace();
var text = doc.Descendants(ns + "item")
.Single(c => c.Attribute("name").Value == "SentTo")
.Elements(ns + "text")
.Select(item => (string)item)
.FirstOrDefault();
输出:
因此,如果您想要获取多个name
attributetext
节点,那么
//This is sample string of array
string[] strArray = new string[2] { "From", "SentTo" };
var list = doc.Descendants(ns + "item")
.Where(c => strArray == null || strArray.Any(x => x.Contains(c.Attribute("name").Value)))
.Elements(ns + "text")
.Select(item => (string)item)
.ToList();
输出:
XPath将满足您的需要。您可以轻松地按类型和属性将元素作为目标。XPath的可能副本将满足您的需要。你可以很容易地通过类型和属性来定位元素。这可能是一条评论,而不是答案。我没有评论的声誉:(然后去获取一些,只需编辑建议就可以轻松获得50条:)这是一条评论,不是答案。我没有评论的声誉:(然后去买一些,只需编辑建议就可以轻松获得50个:)问题改变了吗?我在这里没有看到任何关于HtmlAgilityPack的信息。也许我遗漏了什么?问题改变了吗?我没有看到任何关于HtmlAgilityPack的信息。也许我遗漏了什么?有没有办法在一个Linq查询中同时针对多个标记,比如From、SentTo和SentDate等?@MichaelPhilip这些不是“标记”(元素)-它们是属性值。您当然可以有Where(item=>interestingNames.Contains((string)item.attribute(“name”))
其中interestingNames
是一个列表或一组From、SentTo和SentDate,例如。或者,您可以将所有项目解析到名称/值字典或类似的内容中。这里有很多不同的方法。是否有一种方法可以在单个Linq查询中针对多个标记,例如From、SentTo和SentDate等同时?@MichaelPhilips:这些不是“标记”(元素)-它们是属性值。您当然可以有Where(item=>interestingNames.Contains((string)item.attribute(“name”))
其中interestingNames
是一个列表或一组From、SentTo和SentDate,例如。或者,您可以将所有项目解析到名称/值字典或类似的内容中。这里有许多不同的方法。