我恨透了XML的Namespace, 尤其是xmlns這種預設Namespace。

每次寫Code處理這段都要東查西抄才能搞定,最慘的是連怎麼弄出來自己也模模糊糊。再不然就是走偏門,抓到OuterXML Replace掉xmlns="..."後重新LoadXml,當作沒有Namespace這回事(好像很多人也是這樣搞)。當然,這種態度是不對的,叔叔太頹廢了,小朋友們千萬不可以學~~

今日有幸承蒙chicken大師點化,終於學會怎麼正確處理Default Namespace,特貼文分享。

public static void TestNamesapce()
{
    XmlDocument xd = new XmlDocument();
    xd.LoadXml(@"
<root xmlns=""http://blog.darkthread.net"">
<item></item><item></item>
</root>");
    //太天真了,這樣是查不到的,0分
    Console.WriteLine(xd.SelectNodes("//item").Count);
    //對了,要指定Namespace
    XmlNamespaceManager nsm = 
        new XmlNamespaceManager(xd.NameTable);
    //加入預設的Namesapce,那就是空字串嗎?
    nsm.AddNamespace("", "http://blog.darkthread.net");
    //SelectNodes查詢時要傳入XmlNamespaceManager
    //代誌不像憨人想得那麼簡單... 還是零分
    Console.WriteLine(xd.SelectNodes("//item", nsm).Count);
    //請教chicken大師, 要自己加一個Alias
    nsm.AddNamespace("wtf", "http://blog.darkthread.net");
    //XPATH也要加上Namespace Prefix
    Console.WriteLine(xd.SelectNodes("//wtf:item", nsm).Count);
    //終於得到想到的結果... 感謝大師開示
}

Comments

# by Tom

nsm.AddNamespace("wtf", "http://blog.darkthread.net"); 這一行我比較推薦的做法: nsm.AddNamespace("wtf", xd.DocumentElement.NamesapceURI); 這樣就不用 hardcode namespace string 在程式內, 不管有沒有或是甚麼 namespace 的 xml 文件都可以通吃

# by Jeffrey

to Tom, 謝謝補充! 我原本的程式裡是寫NamespaceURI,改寫範例時怕不夠突顯,就改為Hardcoding,反倒遺漏了要補充這個更扼要的做法,多虧提醒。

Post a comment