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的好少。
posted @ 2006-07-06 14:38  Think  阅读(10245)  评论(12编辑  收藏  举报