诡异的命名空间问题
在处理XML文档的时候,一定要注意,有一个很诡异的问题,就是如果你的元素是含有默认命名空间的,则不仅仅是要添加XmlNamespaceManager,还要特别注意处理默认命名空间的问题。
下面是一个例子
例如我们要解析下面这一段XML文本,获取里面的SessionId
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header>
<Session xmlns="urn:schemas-microsoft-com:xml-analysis" SessionId="A41A11A7-3EEC-443D-8383-E6F1428E555C"/>
</soap:Header><soap:Body><ExecuteResponse xmlns="urn:schemas-microsoft-com:xml-analysis"><return><root xmlns="urn:schemas-microsoft-com:xml-analysis:empty"/></return></ExecuteResponse></soap:Body></soap:Envelope>
代码应该这样写
private string GetSessionId(string response)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(response);
XmlNamespaceManager xnm = new XmlNamespaceManager(doc.NameTable);
xnm.AddNamespace("k", "urn:schemas-microsoft-com:xml-analysis");
xnm.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
XmlNode node = doc.SelectSingleNode("/soap:Envelope/soap:Header/k:Session", xnm);
return node.Attributes["SessionId"].Value;
}
如果不加那个k前缀,就出错了,说找不到对象。这实在是有些弱智
而如果你用LINQ TO XML的话
XDocument doc = XDocument.Load(new StringReader(response));
XNamespace name = "http://schemas.xmlsoap.org/soap/envelope/";
XNamespace empty = "urn:schemas-microsoft-com:xml-analysis";
return doc.Element(name + "Envelope").Element(name + "Header").Element(empty+"Session").Attribute("SessionId").Value;
我再次立场坚定地鄙视一下XML文档中加入命名空间这个设计,凭空添加了很多麻烦,而实际上的好处却不多