2012-03-23 91 views
0

我有点麻烦,获得我想要的输出。我试图通过XML解析并修改一些节点的innertext和属性值。修改xml节点的innertext和属性值

我能够得到的属性部分工作正如我所期望的,但不是节点innertext值。

一个示例XML:

<?xml version="1.0" encoding="utf-8"?> 
<hand:definitions xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:tns="http://joker.org/" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/hand/contract" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:soap="http://schemas.xmlsoap.org/hand/soap/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsaw="http://www.w3.org/2006/05/addressing/hand" xmlns:soap12="http://schemas.xmlsoap.org/hand/soap12/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="projectAppSvc" targetNamespace="http://joker.org/" xmlns:hand="http://schemas.xmlsoap.org/hand/"> 
    <hand:service name="projectAppSvc"> 
    <hand:port name="BasicHttpBinding_IprojectAppSvc" binding="tns:BasicHttpBinding_IprojectAppSvc"> 
     <soap:address location="http://mywebsite:5255/projectappmgr/basic" /> 
    </hand:port> 
    <hand:port name="WSHttpBinding_IprojectAppSvc" binding="tns:WSHttpBinding_IprojectAppSvc"> 
     <soap12:address location="http://mywebsite:5255/projectappmgr/ws" /> 
     <wsa10:Reference> 
     <wsa10:Address>http://mywebsite:5255/projectappmgr/ws</wsa10:Address> 
      <id xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingid"> 
      <Upn>number</Upn> 
      </id> 
     </wsa10:Reference> 
    </hand:port> 
    <hand:port name="NetTcpBinding_IprojectAppSvc" binding="tns:NetTcpBinding_IprojectAppSvc"> 
     <soap12:address location="net.tcp://mywebsite:5256/projectappmgr" /> 
     <wsa10:Reference> 
      <wsa10:Address>net.tcp://mywebsite:5256/projectappmgr</wsa10:Address> 
      <id xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingid"> 
       <Upn>number</Upn> 
      </id> 
      </wsa10:Reference> 
     </hand:port> 
</hand:service> 
</hand:definitions> 

我有以下几点:

public static void ParseXML(XmlNode root) 
{ 
    foreach (XmlNode node in root.ChildNodes) 
    { 
     XmlAttributeCollection attributes = node.Attributes; 

     if (attributes != null) 
      foreach (XmlAttribute attribute in attributes) 
      { 
       Console.WriteLine(attribute.Name + ": " + attribute.Value); 
       if (attribute.Value.Contains("mywebsite")) 
       { 
        Console.WriteLine("found an ATTRIBUTE value that contains localhost"); 
        string origValue = attribute.Value; 
        string modValue = System.Text.RegularExpressions.Regex.Replace(origValue, "mywebsite(:\\d+){0,1}", "NEW_WEBSITE"); 
        attribute.Value = modValue; 
       } 
       ParseXML(node); 
      } 
    } 
} 

这似乎很好地工作,并修改为我所期望的XML,替换属性值包含 “mywebsite” 与“ NEW_WEBSITE”为:

<?xml version="1.0" encoding="utf-8"?> 
<hand:definitions xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:tns="http://joker.org/" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/hand/contract" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:soap="http://schemas.xmlsoap.org/hand/soap/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsaw="http://www.w3.org/2006/05/addressing/hand" xmlns:soap12="http://schemas.xmlsoap.org/hand/soap12/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="projectAppSvc" targetNamespace="http://joker.org/" xmlns:hand="http://schemas.xmlsoap.org/hand/"> 
    <hand:service name="projectAppSvc"> 
    <hand:port name="BasicHttpBinding_IprojectAppSvc" binding="tns:BasicHttpBinding_IprojectAppSvc"> 
     <soap:address location="http://NEW_WEBSITE/projectappmgr/basic" /> 
    </hand:port> 
    <hand:port name="WSHttpBinding_IprojectAppSvc" binding="tns:WSHttpBinding_IprojectAppSvc"> 
     <soap12:address location="http://NEW_WEBSITE/projectappmgr/ws" /> 
     <wsa10:Reference> 
     <wsa10:Address>http://mywebsite:5255/projectappmgr/ws</wsa10:Address> 
      <id xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingid"> 
      <Upn>number</Upn> 
      </id> 
     </wsa10:Reference> 
    </hand:port> 
    <hand:port name="NetTcpBinding_IprojectAppSvc" binding="tns:NetTcpBinding_IprojectAppSvc"> 
     <soap12:address location="net.tcp://NEW_WEBSITE/projectappmgr" /> 
     <wsa10:Reference> 
      <wsa10:Address>net.tcp://mywebsite:5256/projectappmgr</wsa10:Address> 
      <id xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingid"> 
       <Upn>number</Upn> 
      </id> 
      </wsa10:Reference> 
     </hand:port> 
</hand:service> 
</hand:definitions> 

我也想修改以下的innerText:

<wsa10:Address>http://mywebsite:5255/projectappmgr/ws</wsa10:Address> 

我已经试过了foreach循环中执行以下操作:

if (node.InnerText.Contains("mywebsite")) 
{ 
    Console.WriteLine("found an NODE value that contains "mywebsite"); 
    string origValue1 = node.InnerText; 
    string modValue1 = System.Text.RegularExpressions.Regex.Replace(origValue1, 
                   "mywebsite(:\\d+){0,1}", 
                      "NEW_WEBSITE"); 
    node.InnerText = modValue1; 
} 

但是,这显然是不正确的,因为输出是不是想让我的期望。

+0

刚好奇,这是什么'http:// schemas.xmlsoap.org/hand /'命名空间? – 2012-03-23 22:32:24

+0

对不起,这只是一个例子。但它应该是“wsdl”的地方。 – Paul 2012-03-23 22:44:21

回答

1

InnerText返回元素的全部文本内容 - 包括包含的子元素中的文本,所以测试:

if (node.InnerText.Contains("mywebsite")) 

将是真实的在你的XML几乎所有元素,包括根之一,当你执行

node.InnerText = modValue1; 

你消灭了所有的子元素。

你必须明确地测试你正在寻找的元素:

XmlElement element = node as XmlElement; 
if (element != null && 
    element.LocalName == "address" && 
    element.InnerText.Contains("mywebsite")) { 

,或者你应该测试的节点只有一个孩子(文本)的元素:

XmlElement element = node as XmlElement; 
if (element != null && 
    element.InnerText.Contains("mywebsite") && 
    element.ChildNodes.Count == 1) { 
+0

感谢MiMo。我已经离开了一段时间。 – Paul 2012-03-27 20:42:52