Linq を使用して XML/HTML からメタタグを抽出するにはどうすればよいですか?
質問
HTML ファイルから少しのデータを解析しようとしていますが、Linq ステートメントが機能しません。XML/HTML は次のとおりです。以下では、geo.position メタタグから文字列「41.8;12.23」を抽出するにはどうすればよいですか?THX!!
これが私のリンクです
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>
編集:与えられたクエリは何も返しません。「内部」クエリは、必要な 1 つの要素だけではなく、すべてのメタ要素のリストを返すようです。
編集:次の Linq クエリは、同じ XDocument に対して機能し、クラス名 = "data" のテーブルを取得します。
var dataTable =
from el in xdoc.Descendants()
where (string)el.Attribute("class") == "data"
select el;
解決
あ 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
で正しく名前空間を参照していないから来ていることを賭けると思います。ここでそれを行うには、次の2つの方法があります:
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ツリーを照会するときに最も一般的な問題の1つは、XMLツリーがデフォルトの名前空間を持っている場合、開発者は時々XMLの名前空間ではなかったかのようにクエリを書き込んということです。」