【问题标题】:How to extract a meta tag from XML/HTML using Linq?如何使用 Linq 从 XML/HTML 中提取元标记?
【发布时间】:2009-08-21 18:21:01
【问题描述】:

我正在尝试解析 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;

这是我的 Xdocument

<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;

【问题讨论】:

  • 在你的html下划线并点击“代码”按钮
  • 查看此页面以获得完整的标记参考。 stackoverflow.com/editing-help
  • 那么添加你的 linq-statement-that-is-not-working 怎么样?

标签: xml linq meta-tags


【解决方案1】:

span 围绕您的 html 标签?

您可以使用 Xlinq 执行此操作,但它只支持格式良好的 XML。您可能想查看HTML Agility Pack

编辑 - 这对我有用:

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();

【讨论】:

  • 非常感谢,索拉林。我使用 HTML Agility Pack 来获取 XDocumnent——该包添加了 Span。
  • 这不是格式良好的 XML?对解析器来说当然是这样的。
  • 是的,确实如此。我注意到缺少双引号,但没有注意到文档类型实际上已转换为 XML 注释;)
【解决方案2】:

我敢打赌,您遇到的问题来自没有使用 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);

【讨论】:

    【解决方案3】:

    我同意 Thorarin 的观点 - 使用 HTML Agility 包,它更加健壮。

    但是,我怀疑您在使用 LinqToXML 时遇到的问题是因为命名空间。请参阅MSDN here,了解如何在查询中处理它们。

    " 如果您有位于默认命名空间中的 XML,您仍然必须声明一个 XNamespace 变量,并将其与本地名称组合以形成一个在查询中使用的限定名称。

    查询 XML 树时最常见的问题之一是,如果 XML 树具有默认命名空间,开发人员有时会编写查询,就好像 XML 不在命名空间中一样。”

    【讨论】:

    • 谢谢,丹。是的,我是 Agility Pack 的忠实粉丝,它让我遇到了这个问题。 :) 我有其他 Linq 查询 do 对同一个文档起作用。我添加了一个查询示例,但没有添加它为我提取的大表。
    猜你喜欢
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 2011-10-26
    相关资源
    最近更新 更多