如何使用 Linq 从 XML/HTML 中提取元标记?
题
我正在尝试从 HTML 文件中解析一些数据,但我的 Linq 语句不起作用。这是 XML/HTML。下面,如何从 geo.position 元标记中提取字符串“41.8;12.23”?谢谢!!
这是我的 Linq
String longLat = (String)
from el in xdoc.Descendants()
where
(string)el.Name.LocalName == "meta"
& el.FirstAttribute.Name == "geo.position"
select (String) el.LastAttribute.Value;
这是我的 X 文档
<span>
<!--CTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dt -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="application/xhtml+xml; charset=utf-8" http-equiv="Content-Type" />
<meta content="text/css" http-equiv="Content-Style-Type" />
<meta name="geo.position" content="41.8;12.23" />
<meta name="geo.placename" content="RomeFiumicino, Italy" />
<title>RomeFiumicino, Italy</title>
</head>
<body />
</html>
</span>
编辑:我的查询没有返回任何内容。“内部”查询似乎返回所有元元素的列表,而不仅仅是我想要的一个元素。
编辑:以下 Linq 查询针对同一个 XDocument 来检索类名称 =“data”的表
var dataTable =
from el in xdoc.Descendants()
where (string)el.Attribute("class") == "data"
select el;
解决方案
A span
在你周围 html
标签?
您可以使用 XLinq 来完成此操作,但它仅支持格式良好的 XML。您可能想看看 HTML 敏捷包 反而。
编辑 - 这对我有用:
string xml = "...";
var geoPosition = XElement.Parse(xml).Descendants().
Where(e => e.Name.LocalName == "meta" &&
e.Attribute("name") != null &&
e.Attribute("name").Value == "geo.position").
Select(e => e.Attribute("content").Value).
SingleOrDefault();
其他提示
我敢打赌,你遇到的问题是由于没有与XmlNamespaceManager
正确引用的命名空间。这里有两种方法可以做到这一点:
string xml =
@"<span>
<!--CTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN""
""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dt -->
<html xmlns=""http://www.w3.org/1999/xhtml"">
<head>
<meta content=""application/xhtml+xml; charset=utf-8"" http-equiv=""Content-Type"" />
<meta content=""text/css"" http-equiv=""Content-Style-Type"" />
<meta name=""geo.position"" content=""41.8;12.23"" />
<meta name=""geo.placename"" content=""RomeFiumicino, Italy"" />
<title>RomeFiumicino, Italy</title>
</head>
<body />
</html>
</span>";
string ns = "http://www.w3.org/1999/xhtml";
XmlNamespaceManager nsm;
// pre-Linq:
XmlDocument d = new XmlDocument();
d.LoadXml(xml);
nsm = new XmlNamespaceManager(d.NameTable);
nsm.AddNamespace("h", ns);
Console.WriteLine(d.SelectSingleNode(
"/span/h:html/h:head/h:meta[@name='geo.position']/@content", nsm).Value);
// Linq - note that you have to create an XmlReader so that you can
// use its NameTable in creating the XmlNamespaceManager:
XmlReader xr = XmlReader.Create(new StringReader(xml));
XDocument xd = XDocument.Load(xr);
nsm = new XmlNamespaceManager(xr.NameTable);
nsm.AddNamespace("h", ns);
Console.WriteLine(
xd.XPathSelectElement("/span/h:html/h:head/h:meta[@name='geo.position']", nsm)
.Attribute("content").Value);
我同意Thorarin - 使用HTML敏捷性包,它更强大
。不过,我怀疑你使用LinqToXML遇到的问题是因为命名空间的。请参见 MSDN这里如何处理他们在您的查询。
”如果你有XML是一个默认的命名空间,仍然必须声明的XNamespace变量,并与当地的名称结合起来做一个合格的名称在查询中使用。
一个最常见的问题查询XML树时,如果XML树有一个默认的命名空间,开发商有时写查询,就好像XML不是在命名空间“。
不隶属于 StackOverflow