我一直习惯用正则式来处理文本,包括XML文件,只是偶尔才用一下XmlDocument和XPath之类的东东。
最近做SP,移到的MISC系统从1.5升级到了1.6,它的1.5版用的是简单的XML格式响应和请求,现在的1.6版使用了标准的SOAP信息,一个标准的MISC对SP的请求可能是这样的:
此时,需要对命名空间一一定义:
感觉周围的开发者用XPath和XSTL的好少。
最近做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-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 " ); // 取不到任何节点
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); // 注意,就算是用默认命名空间的节点,也要为命名空间定义一个名字,并使用这个名字。
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的好少。