C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: C# XMLのSelectSingleNodeでノードが取れ


(過去ログ 119 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■69761 / inTopicNo.1)  C# XMLのSelectSingleNodeでノードが取れ
  
□投稿者/ まめしば (1回)-(2014/01/28(Tue) 15:49:21)

分類:[.NET 全般] 

VS2008/Windows7

お世話様です。
標題のメソッドを使ってXMLの操作を行っています。
利用するのは初めてではないのですが、現在取得しようとしてる内容だとノードが取得できず、
その理由が全く分からないのでどなたか御教示ください。

やっている流れとしては
HTTPリクエストのレスポンスをXmlDocumentでロードし、その後SelectSingleNode()でトップのノード名指定をしています。
以下にコードとXmlDocumentのInnerXmlの内容を記載します。

----------------------------------------------------------------
XmlNode node = xml.SelectSingleNode("./WMS_Capabilities");
→nodeが取得できずnullとなる。

----------------------------------------------------------------
<?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?>
<WMS_Capabilities>
<Service>
</Service>
</WMS_Capabilities>
(属性などは視認性を考慮し削除しています)

宜しくお願い致します。
引用返信 編集キー/
■69762 / inTopicNo.2)  Re[1]: C# XMLのSelectSingleNodeでノードが取れ
□投稿者/ Hongliang (158回)-(2014/01/28(Tue) 16:18:37)
少なくとも見える範囲では間違っていないように見えます。
変数xmlはXmlDocumentオブジェクトですよね?

デバッガでブレークするなどしてxml.ChildNodesを確認してみて下さい。
WMS_Capabilitiesを指すXmlElementは存在していますか?

// ./WMS_Capabilities の先頭の.は無い方が自然じゃないかなぁ。

引用返信 編集キー/
■69763 / inTopicNo.3)  Re[2]: C# XMLのSelectSingleNodeでノードが取れ
□投稿者/ まめしば (2回)-(2014/01/28(Tue) 16:47:22)
>>Hongliang さん
レスありがとうございます。
自分でも特に間違いはないと思ってはいるのですが・・・。
(いままでにない経験のため)

ちなみにChildNodesにも含まれています。実際xml.LastChildでは該当の要素が取れるので。
ただその後取得したノードで同メソッドを実行するとやはり正常に取得できないみたいです。
何かxpath部分のコードの問題でしょうか・・・。

ちなみに御指摘頂いたコロンなしや"//WMS_Capabilities"、"WMS_Capabilities"などいくつか試してみましたが
結果は変わりませんでした。

引用返信 編集キー/
■69764 / inTopicNo.4)  Re[3]: C# XMLのSelectSingleNodeでノードが取れ
□投稿者/ Hongliang (159回)-(2014/01/28(Tue) 16:52:51)
LastChildで取れるのなら、そのLocalNameとWMS_Capabilitiesが等しいかどうかをチェックしてみて下さい。

ところで、まさかとは思いますが、xmlns属性が存在していたりしませんか?
引用返信 編集キー/
■69766 / inTopicNo.5)  Re[4]: C# XMLのSelectSingleNodeでノードが取れ
□投稿者/ まめしば (4回)-(2014/01/28(Tue) 17:27:09)
>>Hongliang さん
> LastChildで取れるのなら、そのLocalNameとWMS_Capabilitiesが等しいかどうかをチェックしてみて下さい。
> ところで、まさかとは思いますが、xmlns属性が存在していたりしませんか?
度々ありがとうございます。
LocalNameとWMS_Capabilitiesの文字列比較では同一でした。
xmlns属性ですが御指摘の通り含まれているようです。
(属性を含むXMLは以下の通り)
勉強不足で申し訳ないのですが、これが原因に関わるものなのでしょうか。

<?xml version="1.0" encoding="ISO-8859-1"?>
<WMS_Capabilities xsi:schemaLocation="http://www.opengis.net/wms http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd http://mapserver.gis.umn.edu/mapserver http://www.finds.jp/ws/kiban2500wms.cgi?service=WMS&version=1.3.0&request=GetSchemaExtension" xmlns:ms="http://mapserver.gis.umn.edu/mapserver" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sld="http://www.opengis.net/sld" xmlns="http://www.opengis.net/wms" version="1.3.0">
<Service> <Name>WMS</Name> <Title>KIBAN 2500 WMS</Title> <OnlineResource xlink:href="http://www.finds.jp/ws/kiban2500wms.cgi?" xmlns:xlink="http://www.w3.org/1999/xlink"/> <ContactInformation> </ContactInformation> <MaxWidth>2048</MaxWidth> <MaxHeight>2048</MaxHeight></Service>
</WMS_Capabilities>
引用返信 編集キー/
■69767 / inTopicNo.6)  Re[5]: C# XMLのSelectSingleNodeでノードが取れ
□投稿者/ Hongliang (160回)-(2014/01/28(Tue) 17:34:51)
あ、名前空間付きでしたか。
名前空間付きの要素については、SelectSingleNode(string, XmlNamespaceManager)を使用する必要があります。
また仕様上、既定の名前空間の場合でも、検索する際にはXmlNamespaceManagerに(任意の)接頭辞付きで
名前空間URIを登録し、かつXPathにも名前空間接頭辞を指定する必要があります。

具体的にはこんな感じ。

var nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("a", "http://www.opengis.net/wms");
var node = xml.SelectSingleNode("/a:WMS_Capabilities", nsmgr);

XML名前空間に関してはご自分でお調べ下さい。

引用返信 編集キー/
■69770 / inTopicNo.7)  Re[5]: C# XMLのSelectSingleNodeでノードが取れ
□投稿者/ 魔界の仮面弁士 (514回)-(2014/01/28(Tue) 17:52:36)
No69766 (まめしば さん) に返信
> xmlns属性ですが御指摘の通り含まれているようです。
> 勉強不足で申し訳ないのですが、これが原因に関わるものなのでしょうか。

関わります。


static void CW(XmlNode node)
{
    if (node == null) Console.WriteLine(" (null) ");
    else Console.WriteLine(node.OuterXml);
}

static void Main()
{
    XmlDocument doc0 = new XmlDocument();
    doc0.LoadXml(@"<hoge />");

    XmlDocument doc1 = new XmlDocument();
    doc1.LoadXml(@"<hoge xmlns='abc' />");

    XmlDocument doc2 = new XmlDocument();
    doc2.LoadXml(@"<hoge xmlns='xyz' />");

    XmlDocument doc3 = new XmlDocument();
    doc3.LoadXml(@"<sample:hoge xmlns:sample='abc' />");


    Console.WriteLine(" ----- ルート要素 ----- ");
    CW(doc0.DocumentElement);
    CW(doc1.DocumentElement);
    CW(doc2.DocumentElement);
    CW(doc3.DocumentElement);

    Console.WriteLine(" ----- /hoge ----- ");
    CW(doc0.SelectSingleNode("/hoge"));
    CW(doc1.SelectSingleNode("/hoge"));
    CW(doc2.SelectSingleNode("/hoge"));
    CW(doc3.SelectSingleNode("/hoge"));

    Console.WriteLine(" ----- /*[namespace-uri()='abc'][local-name()='hoge'] ----- ");
    CW(doc0.SelectSingleNode("/*[namespace-uri()='abc'][local-name()='hoge']"));
    CW(doc1.SelectSingleNode("/*[namespace-uri()='abc'][local-name()='hoge']"));
    CW(doc2.SelectSingleNode("/*[namespace-uri()='abc'][local-name()='hoge']"));
    CW(doc3.SelectSingleNode("/*[namespace-uri()='abc'][local-name()='hoge']"));

    Console.WriteLine(" ----- 名前空間を指定 ----- ");
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
    nsmgr.AddNamespace("foo", "abc");
    nsmgr.AddNamespace("bar", "xyz");
    CW(doc0.SelectSingleNode("/foo:hoge", nsmgr));
    CW(doc1.SelectSingleNode("/foo:hoge", nsmgr));
    CW(doc2.SelectSingleNode("/foo:hoge", nsmgr));
    CW(doc3.SelectSingleNode("/foo:hoge", nsmgr));
}

引用返信 編集キー/
■69773 / inTopicNo.8)  Re[1]: C# XMLのSelectSingleNodeでノードが取れ
□投稿者/ まめしば (6回)-(2014/01/28(Tue) 19:49:41)
>> Hongliang さん、魔界の仮面弁士さん
早急なご回答ありがとうございます。
御指摘頂いた内容を元に調べ、無事望む結果が得られるようになりました。
非常に丁寧なサンプルコードも頂けて非常に助かりました。

今回サーバサイドのバージョンアップに伴い対応を加えておりましたが、
旧仕様では名前空間の定義がなかったため、まったく気にしておりませんでした。

まだ記述方法に慣れていないだけかもしれませんが、
若干可読性が悪くなって四苦八苦しております。。。

ともあれ当質問は解決済みとさせて頂きます。
本当にありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -