以前操作xml一般用下面這種方式:
好處是XDocument 能使用linq
xmlPath = “path”; XDocument myXDoc = XDocument.Load(xmlPath); IEnumerable<XElement> targetNodes = from target in myXDoc.Descendants("signal") where target.Attribute("signalname").Value == name select target; XElement element = targetNodes.First();
這種只方式遇到帶名稱空間的就坑了,看來參考中的兩篇博客,發現以下方法可以操作
StreamReader reader=new StreamReader("path");
XmlReader reader = XmlReader.Create(respStream); XElement root = XElement.Load(reader); XmlNameTable nameTable = reader.NameTable; XmlNamespaceManager namespaceManager = new XmlNamespaceManager(nameTable); namespaceManager.AddNamespace("wfs", "http://www.opengis.net/wfs"); namespaceManager.AddNamespace("ows", "http://www.opengis.net/ows"); namespaceManager.AddNamespace("ocg", "http://www.opengis.net/ocg"); namespaceManager.AddNamespace("xsi","http://www.w3.org/2001/XMLSchema-instance"); namespaceManager.AddNamespace("gml", "http://www.opengis.net/gml"); namespaceManager.AddNamespace("ogc", "http://www.opengis.net/ogc"); namespaceManager.AddNamespace("xlink", "http://www.w3.org/1999/xlink"); namespaceManager.AddNamespace("myWorld","http://www.myWorld.com"); XElement child1 = root.XPathSelectElement("./wfs:FeatureTypeList", namespaceManager); XElement child2 = child1.XPathSelectElement("./wfs:FeatureType", namespaceManager);//這里是重點,child2既然是child1的子節點,就必須調用child1的XPathSelectElement方法
上面的方法中也看到了,如果child2是child1的子節點,就必須調用child1的XPathSelectElement方法,這樣如果想取一個縱深很深的XElement,是不是要手動一個個的找到其Parent節點,再用上面的辦法寫一堆。。。
child.XPathSelectElement()
想起了WPF中查找XMAL中指定節點的方法,於是我使用遞歸寫了下面的辦法來獲取子節點。
調用GetNode,傳入的參數是前一段代碼的,最后xElementList 中得到的就是需要獲取的XElement的集合。
如果使用注釋中的代碼,返回的是xml文檔中的第一個檢索到的XElement。
List<XElement> xElementList = new List<XElement>();
/// <summary>
/// 獲取子節點(不完善,根加點的第一級子節點無法獲取,有需要的話需單獨調用一次XElement elelment = root.XPathSelectElement(nodePath, xmlNameSpaceManager);)
/// </summary>
/// <param name="root">根節點</param>
/// <param name="xmlNameSpaceManager">命名空間管理器(我自己這么叫它)</param>
/// <param name="nodeSpace">需獲取的節點的命名空間</param>
/// <param name="nodeName">需獲取的節點的名稱,如<ows:DCP>,ows是名稱空間,DCP是其名字</param>
/// <returns></returns>
private XElement GetNode(XElement root,XmlNamespaceManager xmlNameSpaceManager,string nodeSpace,string nodeName) { List<XElement> childList = root.Elements().ToList(); for (int i = 0; i < childList.Count; i++) { XElement child = childList[i]; var node = GetElement(child, xmlNameSpaceManager, nodeSpace, nodeName); if (node != null) { xElementList.Add(node); //return node; } else { node = GetNode(child, xmlNameSpaceManager, nodeSpace, nodeName); if (node != null) xElementList.Add(node); //return node; } } return xElementList;
//return node;
}
private XElement GetElement(XElement root, XmlNamespaceManager xmlNameSpaceManager, string nodeSpace, string nodeName)
{
var enumerator = xmlNameSpaceManager.GetEnumerator(); while (enumerator.MoveNext()) { var nameSpace = enumerator.Current.ToString(); if (nameSpace.Equals(nodeSpace)) { string nodePath = "./" + nameSpace + ":" + nodeName; XElement elelment = root.XPathSelectElement(nodePath, xmlNameSpaceManager); if (elelment != null) return elelment; } } return null; }
參考:
http://www.cnblogs.com/HQFZ/p/4788428.html
http://www.cnblogs.com/landeanfen/p/4636102.html