2015-09-25 84 views
0

我有一個帶有按鈕的網頁。點擊後,我將我的變量傳遞給一個類來創建一個xml文件。我試圖在名爲Message的元素下添加我的名稱空間。它工作不正常。序列化爲xml和名稱空間放置

這裏是我的類:

using System.Xml.Serialization; 

// 
// This source code was auto-generated by xsd, Version=4.0.30319.1. 
// 


/// <remarks/> 
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)] 


public partial class Request 
    { 

    private string sNameField; 



    /// <remarks/> 
    public string SName 
    { 
     get 
     { 
      return this.sNameField; 
     } 
     set 
     { 
      this.sNameField = value; 
     } 
    } 



    /// <remarks/> 
    public Message Message 
    { 
     get 
     { 
      return this.messageField; 
     } 
     set 
     { 
      this.messageField = value; 
     } 
    } 
} 

/// <remarks/> 
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false)] 

public partial class Message 
{ 

    private AddO addOField; 

    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://pd.com")] 
    public AddO AddO 
    { 
     get 
     { 
      return this.addOField; 
     } 
     set 
     { 
      this.addOField = value; 
     } 
    } 
} 

/// <remarks/> 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://pd.com")] 
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://pd.com", IsNullable = false)] 
public partial class AddO 
{ 

    private CaseD caseD; 

    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.a.com")] 
    public CaseD CaseD 
    { 
     get 
     { 
      return this.caseDField; 
     } 
     set 
     { 
      this.caseDField = value; 
     } 
    } 
} 

/// <remarks/> 
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.a.com")] 
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.a.com", IsNullable = false)] 
public partial class CaseD 
{ 

    private CaseA caseAField; 

    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.z.com")] 
    public CaseA CaseA 
    { 
     get 
     { 
      return this.caseAField; 
     } 
     set 
     { 
      this.caseAField = value; 
     } 
    } 
} 

/// <remarks/> 
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.z.com")] 
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.z.com", IsNullable = false)] 
public partial class CaseA 
{ 

    private Doc docField; 

    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.a.com")] 
    public DocuE DocE 
    { 
     get 
     { 
      return this.docEField; 
     } 
     set 
     { 
      this.docEField = value; 
     } 
    } 
} 

這裏是我的按鈕事件:

<?xml version="1.0" encoding="utf-8"?> 
<Request xmlns:a="http://www.a.com"> 
    <SName>hi</SName> 

    <Message> 
    <addO xmlns="http://pd.com"> 
     <a:caseD> 
     <caseA xmlns="http://www.z.com"> 

     </caseA> 
     </a:caseD> 
    </addO> 
    </Message> 
</Request> 

我需要的命名空間是僅在:

caseA caseA = new caseA(); 



      caseD caseD = new caseD(); 
      caseD.caseA = caseA; 



      addO addO = new addO(); 
      addO.caseD = caseD; 



      Message Message = new Message(); 
      Message.addO = addO; 

      Request Request = new Request(); 
      Request.Message = Message; 

      Request.SName = "Hi"; 


      XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
      ns.Add("z", "http://www.z.com"); 
      ns.Add("pd", "http://pd.com"); 
      ns.Add("a", "http://www.a.com"); 

    XmlSerializer serializer = new XmlSerializer(typeof(Request), new Type[] {typeof(Message), typeof(addO), typeof(caseD), typeof(caseA)}); 
      StreamWriter writer = new StreamWriter(Server.MapPath("~/images/test.xml")); 
      serializer.Serialize(writer, Request, ns); 

我在XML得到這個Message元素:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Request> 

<SName>Hi</SName> 

    <Message> 
     <pd:addO 
xmlns:a="http://www.a.com" 
xmlns:z="http://www.z.com" 
xmlns:pd="http://pd.com"> 
      <a:caseD> 
       <z:caseA> 

       </z:caseA> 
      </a:caseD> 
     </pd:addO> 
    </Message> 
</Request> 
+0

您可能需要使用'XmlWriter'仔細寫出來的XML你喜歡的方式。請注意,由於兩個版本都與XML的觀點相同,因此.Net中沒有太多提示移動前綴聲明的位置。 –

+0

你的測試用例不能編譯 - 'Doc'和'DocuE'類型丟失,字段'Request.messageField'丟失。你可以創建一個[Minimal,Complete,and Verifiable example](http://stackoverflow.com/help/mcve)你的問題嗎? – dbc

回答

0

無論根元素還是子元素都具有名稱空間定義 - 您的兩個XML樣本在語義上是相同的。

不過,如果你面對的是不能正確處理這樣的接收系統,你可以利用[XmlAnyElementAttribute]屬性做嵌套的序列化XmlSerializer,嵌入AddO元件的內部序列化的結果(包括所需的命名空間)在Request的外部序列化中。

首先,你需要一些擴展方法往返於XElement類序列化,以及其他相關工具:

public static class XmlExtensions 
{ 
    public static XmlSerializerNamespaces NoStandardXmlNamespaces() 
    { 
     var ns = new XmlSerializerNamespaces(); 
     ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines. 
     return ns; 
    } 

    public static T Deserialize<T>(this XContainer element, XmlSerializer serializer = null) 
    { 
     using (var reader = element.CreateReader()) 
     { 
      object result = (serializer ?? new XmlSerializer(typeof(T))).Deserialize(reader); 
      if (result is T) 
       return (T)result; 
     } 
     return default(T); 
    } 

    public static XElement SerializeToXElement<T>(this T obj) 
    { 
     return obj.SerializeToXElement(null, NoStandardXmlNamespaces()); 
    } 

    public static XElement SerializeToXElement<T>(this T obj, XmlSerializerNamespaces ns) 
    { 
     return obj.SerializeToXElement(null, ns); 
    } 

    public static XElement SerializeToXElement<T>(this T obj, XmlSerializer serializer, XmlSerializerNamespaces ns) 
    { 
     var doc = new XDocument(); 
     using (var writer = doc.CreateWriter()) 
      (serializer ?? new XmlSerializer(obj.GetType())).Serialize(writer, obj, ns); 
     var element = doc.Root; 
     if (element != null) 
      element.Remove(); 
     return element; 
    } 

    public static T LoadFromXML<T>(this string xmlString, XmlSerializer serializer = null) 
    { 
     serializer = serializer ?? new XmlSerializer(typeof(T)); 

     T returnValue = default(T); 
     using (StringReader reader = new StringReader(xmlString)) 
     { 
      object result = serializer.Deserialize(reader); 
      if (result is T) 
      { 
       returnValue = (T)result; 
      } 
     } 
     return returnValue; 
    } 

    public static string GetXml<T>(this T obj, XmlSerializerNamespaces ns, bool? standalone) 
    { 
     return GetXml(obj, null, ns, standalone); 
    } 

    public static string GetXml<T>(T obj, XmlSerializer serializer, XmlSerializerNamespaces ns, bool? standalone) 
    { 
     serializer = serializer ?? new XmlSerializer(obj.GetType()); 
     using (var textWriter = new Utf8StringWriter()) 
     { 
      var settings = new XmlWriterSettings() { Indent = true, IndentChars = " " }; // For cosmetic purposes. 
      using (var xmlWriter = XmlWriter.Create(textWriter, settings)) 
      { 
       if (standalone != null) 
        xmlWriter.WriteStartDocument(standalone.Value); 
       serializer.Serialize(xmlWriter, obj, ns); 
      } 
      return textWriter.ToString(); 
     } 
    } 

    public static string RootXmlElementName(this Type type) 
    { 
     var xmlRoot = type.GetCustomAttribute<XmlRootAttribute>(); 
     if (xmlRoot != null && !string.IsNullOrEmpty(xmlRoot.ElementName)) 
      return xmlRoot.ElementName; 
     return type.Name; 
    } 
} 

public class Utf8StringWriter : StringWriter 
{ 
    public override Encoding Encoding 
    { 
     get { return Encoding.UTF8; } 
    } 
} 

接下來,定義類,包括如下Message類。請注意,在你的問題中的類不進行編譯(缺少一些類型的),所以我已經簡化了他們:現在

public class Request 
{ 
    public string SName { get; set; } 

    public Message Message { get; set; } 
} 

public static class Namespaces 
{ 
    public const string pd = "http://pd.com"; 
    public const string a = "http://www.a.com"; 
    public const string z = "http://www.z.com"; 

    public static XmlSerializerNamespaces GetNamespaces() 
    { 
     XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
     ns.Add("pd", pd); 
     ns.Add("a", a); 
     ns.Add("z", z); 
     return ns; 
    } 
} 

public class Message 
{ 
    [XmlIgnore] 
    public AddO AddO { get; set; } 

    // Do nested serialization here 
    [XmlAnyElement] 
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)] 
    public XElement[] AddOXml 
    { 
     get 
     { 
      if (AddO == null) 
       return null; 
      var ns = Namespaces.GetNamespaces(); 
      var element = AddO.SerializeToXElement(ns); 
      element.Name = element.Name.Namespace + "addO"; 
      return new[] { element }; 
     } 
     set 
     { 
      if (value == null || value.Length == 0) 
       AddO = null; 
      AddO = value.Select(x => { x.Name = x.Name.Namespace + typeof(AddO).RootXmlElementName(); return x.Deserialize<AddO>(); }).FirstOrDefault(); 
     } 
    } 
} 

[XmlRoot(Namespace = Namespaces.pd)] 
public class AddO 
{ 
    [XmlElement("caseD", Namespace = Namespaces.a)] 
    public CaseD CaseD { get; set; } 
} 

public class CaseD 
{ 
    [XmlElement("caseA", Namespace = Namespaces.z)] 
    public CaseA CaseA { get; set; } 
} 

public class CaseA 
{ 
    public string Value { get; set; } 
} 

,測試:

public class TestClass 
{ 
    public static void Test() 
    { 
     var request = new Request 
     { 
      SName = "Hi", 
      Message = new Message 
      { 
       AddO = new AddO 
       { 
        CaseD = new CaseD { CaseA = new CaseA { Value = "Test Value" } }, 
       } 
      } 
     }; 
     var xml = request.GetXml(XmlExtensions.NoStandardXmlNamespaces(), true); 
     Debug.WriteLine(xml); 
     var request2 = xml.LoadFromXML<Request>(); 
     Debug.WriteLine(request2.GetXml(XmlExtensions.NoStandardXmlNamespaces(), true)); 

     Debug.Assert(request.Message.AddO.CaseD.CaseA.Value == request2.Message.AddO.CaseD.CaseA.Value); // No assert. 
    } 
} 

原型fiddle。 XML輸出是:

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<Request> 
    <SName>Hi</SName> 
    <Message> 
     <pd:addO xmlns:z="http://www.z.com" xmlns:a="http://www.a.com" xmlns:pd="http://pd.com"> 
      <a:caseD> 
       <z:caseA> 
        <z:Value>Test Value</z:Value> 
       </z:caseA> 
      </a:caseD> 
     </pd:addO> 
    </Message> 
</Request> 
相關問題