19

私は、特に醜い「ライブ」HTML を取り込んで、HTML Agility Pack を使用して正式な XML DOM に強制するプロジェクトを持っています。私ができるようにしたいのは、Linq to XML でこれをクエリして、必要なビットをかき出すことです。ここで説明する方法を使用して HtmlDocument を XDocument に解析していますが、これに対してクエリを実行しようとすると、名前空間を処理する方法がわかりません。ある特定のドキュメントでは、元の HTML は実際には次のタグを含む適切にフォーマットされていない XHTML でした。

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

このドキュメントからクエリを実行しようとすると、名前空間属性が次のようなことを妨げているようです:

var x = xDoc.Descendants("div");
// returns null

どうやらこれらの「div」タグの場合、LocalName のみが「div」ですが、適切なタグ名は名前空間と「div」です。XML 名前空間の問題についていくつか調査を試みましたが、次の方法でクエリを実行することで名前空間をバイパスできるようです。

var x = 
    (from x in xDoc.Descendants()
     where x.Name.LocalName == "div"
     select x);
// works

ただし、これはかなりハックなソリューションのように見え、名前空間の問題に適切に対処していません。私が理解しているように、適切な XML ドキュメントには複数の名前空間を含めることができるため、それを処理する適切な方法は、クエリを実行している名前空間を解析することです。他の誰かがこれをしなければならなかったことがありますか?私はそれを複雑にしていますか?HtmlDocumentに固執し、XPathでクエリを実行するだけで、これらすべてを回避できることはわかっていますが、可能であれば、私が知っていること(Linq)に固執し、さらに名前空間を設定していないことも知りたいです-今後の関連する問題。

この状況で名前空間を処理する適切な方法は何ですか?

4

3 に答える 3

17

使用してLocalNameも問題ないはずです。それがどの名前空間にあるかを気にしないのであれば、私はそれをハックとはまったく考えません.

必要な名前空間が分かっていて、それを指定したい場合は、次のことができます。

var ns = "{http://www.w3.org/1999/xhtml}";
var x  = xDoc.Root.Descendants(ns + "div");

( MSDN リファレンス)

ドキュメントで使用されているすべての名前空間のリストを取得することもできます。

var namespaces = (from x in xDoc.Root.DescendantsAndSelf()
                  select x.Name.Namespace).Distinct();

それを使用してこれを行うことができると思いますが、実際にはそれほどハックではありません:

var x = namespaces.SelectMany(ns=>xDoc.Root.Descendants(ns+"div"));
于 2008-10-08T15:32:10.113 に答える
2

ほとんどの場合そうであるように、名前空間が XML のルート要素によって宣言されることがわかっている場合は、次のようにすることができます。

var ns = xDoc.Root.Name.Namespace;
var x = xDoc.Descendants(ns + "div");
于 2012-08-06T16:57:59.540 に答える
-11

あなたのGoogle-fuはあなたに失敗すると思います:

http://www.google.com.au/search?hl=en&q=linq+xml+名前空間

于 2008-10-08T15:34:14.820 に答える