<?xml version="1.0" encoding="utf-8" ?> <root> <h:table xmlns:h=http://www.w3.org/TR/html4/> <h:tr> <h:td>Apples</h:td> <h:td>Bananas</h:td> </h:tr> </h:table> <f:table xmlns:f="http://www.w3schools.com/furniture"> <f:name>African Coffee Table</f:name> <f:width>80</f:width> <f:length>120</f:length> </f:table> <table> <name>Microsoft Visual C# 2008 Step by Step</name> <author>John Sharp</author> </table> </root>
在 xml 的查詢中, Namespace 的處理往往都需事先知道後, 才能在程式中設定.
例如以下的程式:
XmlDocument doc = new XmlDocument(); doc.Load(@".\ns.xml"); XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable); mgr.AddNamespace("h", "http://www.w3.org/TR/html4/"); mgr.AddNamespace("f", http://www.w3schools.com/furniture);如果 ns.xml 檔案的 namespace 多了一個, 或是對應的 url 路徑異動了, 程式大概就要修改, 然後重新上版.
因為我覺得這樣蠻麻煩的, 所以寫了以下兩個方式來做 namespace 的設定.
- 使用 Regular Expression, 找出所有 xmlns:<perefix>="<uri>" 的 pattern.
程式參考如下:XmlDocument doc = new XmlDocument(); doc.Load(@".\ns.xml"); XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable); Regex reg = new Regex("xmlns[:]?(?<prefix>.*?)\\s*=\\s*\"(?<uri>.*?)\"", RegexOptions.IgnoreCase); Match match = reg.Match(doc.OuterXml); while (match.Success) { if (!mgr.HasNamespace(match.Groups["prefix"].Value)) { mgr.AddNamespace(match.Groups["prefix"].Value, match.Groups["uri"].Value); } match = match.NextMatch(); }
- 使用 SelectNodes(), 查出所有的 XmlDocument 中所有的 Node, 再針對屬性 Prefix 為 xmlns 的資料做設定.
程式參考如下 :
XmlDocument doc = new XmlDocument(); doc.Load(@".\ns.xml"); XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable); XmlNodeList lstNodes = doc.SelectNodes("//child::*"); foreach (XmlNode node in lstNodes) { foreach (XmlAttribute attr in node.Attributes) { if (attr.Prefix.Equals("xmlns")) { if (!mgr.HasNamespace(attr.LocalName)) { mgr.AddNamespace(attr.LocalName, attr.Value); } } } }
另外, 要避免使用 xmlns=http://www.w3.org/TR/html4/, 這種預設 namespace 的用法, 以免後續的 XPath 查詢出問題.
補充一下設定 namespace 後的查詢方式:
//查詢xmlns:h="http://www.w3.org/TR/html4/"的<h:table> XmlNodeList lstNode = doc.SelectNodes("//h:table", mgr); foreach (System.Xml.XmlNode node in lstNode) { Console.WriteLine(node.OuterXml); } //查詢xmlns:f="http://www.w3schools.com/furniture"的<f:table> lstNode = doc.SelectNodes("//f:table", mgr); foreach (System.Xml.XmlNode node in lstNode) { Console.WriteLine(node.OuterXml); } //查詢沒有設定NameSpace的<table> lstNode = doc.SelectNodes("//table", mgr); foreach (System.Xml.XmlNode node in lstNode) { Console.WriteLine(node.OuterXml); }
沒有留言:
張貼留言