XPath遇上命名空间

        
        我一直习惯用正则式来处理文本,包括XML文件,只是偶尔才用一下XmlDocument和XPath之类的东东。

        最近做SP,移到的MISC系统从1.5升级到了1.6,它的1.5版用的是简单的XML格式响应和请求,现在的1.6版使用了标准的SOAP信息,一个标准的MISC对SP的请求可能是这样的:
<? xml version="1.0" encoding="utf-8" ?>
< SOAP-ENV:Envelope
 
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd
="http://www.w3.org/2001/XMLSchema"
  xmlns:SOAP-ENV
="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:SOAP-ENC
="http://schemas.xmlsoap.org/soap/encoding/" >
    
< SOAP-ENV:Header >
        
< TransactionID  xmlns ="http://www.monternet.com/dsmp/schemas/" > 06070516230084 </ TransactionID >
    
</ SOAP-ENV:Header >
    
< SOAP-ENV:Body >
        
< SyncOrderRelationReq  xmlns ="http://www.monternet.com/dsmp/schemas/" >
            
< Version > 1.5.0 </ Version >
            
< MsgType > SyncOrderRelationReq </ MsgType >
            
< Send_Address >
                
< DeviceType > 0 </ DeviceType >
                
< DeviceID > 0011 </ DeviceID >
            
</ Send_Address >
            
< Dest_Address >
                
< DeviceType > 400 </ DeviceType >
                
< DeviceID > 0 </ DeviceID >
            
</ Dest_Address >
            
< FeeUser_ID >
                
< UserIDType > 1 </ UserIDType >
                
< MSISDN > 13800138000 </ MSISDN >
                
< PseudoCode >
                
</ PseudoCode >
            
</ FeeUser_ID >
            
< DestUser_ID >
                
< UserIDType > 1 </ UserIDType >
                
< MSISDN > 13800138000 </ MSISDN >
                
< PseudoCode ></ PseudoCode >
            
</ DestUser_ID >
            
< LinkID > LinkID </ LinkID >
            
< ActionID > 1 </ ActionID >
            
< ActionReasonID > 1 </ ActionReasonID >
            
< SPID > 900000 </ SPID >
            
< SPServiceID > abcd </ SPServiceID >
            
< AccessMode > 3 </ AccessMode >
            
< FeatureStr ></ FeatureStr >
        
</ SyncOrderRelationReq >
    
</ SOAP-ENV:Body >
</ SOAP-ENV:Envelope >

哈哈,这下麻烦大了,不仅SOAP标准本身定义了多个命名空间,而且卓望的人还给移动定义了个命名空间(但是,其实并没有提供Schema)。
        对于这种带有命名空间的XML进行SelectNodes,可不能再使用简单XPath语句就行:

string  xml  =   " " ;
XmlDocument xmlDoc 
=   new  XmlDocument();
xmlDoc.LoadXml(xml);
xmlDoc.SelectNodes(
" //SOAP-ENV:Header/TransationID " ); // 取不到任何节点

        此时,需要对命名空间一一定义:
             string  xml  =   " " ;
            XmlDocument xmldoc 
=   new  XmlDocument();
            xmldoc.LoadXml(xml);
            XmlNamespaceManager xnm 
=   new  XmlNamespaceManager(xmldoc.NameTable);
            xnm.AddNamespace(
" SOAP-ENV " , " http://schemas.xmlsoap.org/soap/envelope/ " );
            xnm.AddNamespace(
" Mo " , " http://www.monternet.com/dsmp/schemas/ " );
            xmldoc.SelectNodes(
" //SOAP-ENV:Header/Mo:TransationID " ,xnm); // 注意,就算是用默认命名空间的节点,也要为命名空间定义一个名字,并使用这个名字。

        感觉周围的开发者用XPath和XSTL的好少。

你可能感兴趣的:(xpath)