以前操作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", "");
namespaceManager.AddNamespace("ows", "");
namespaceManager.AddNamespace("ocg", "");
namespaceManager.AddNamespace("xsi","");
namespaceManager.AddNamespace("gml", "");
namespaceManager.AddNamespace("ogc", "");
namespaceManager.AddNamespace("xlink", "");
namespaceManager.AddNamespace("myWorld","");
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>根节点</param>
/// <param>命名空间管理器(我自己这么叫它)</param>
/// <param>需获取的节点的命名空间</param>
/// <param>需获取的节点的名称,如<ows:DCP>,ows是名称空间,DCP是其名字</param>
/// <returns></returns>
//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; }