2011-05-17 50 views
3

鑑於這種通用串行化代碼:刪除命名空間在XML序列化

public virtual string Serialize(System.Text.Encoding encoding) 
{ 
System.IO.StreamReader streamReader = null; 
System.IO.MemoryStream memoryStream = null; 

memoryStream = new System.IO.MemoryStream(); 
System.Xml.XmlWriterSettings xmlWriterSettings = new System.Xml.XmlWriterSettings(); 
xmlWriterSettings.Encoding = encoding; 
System.Xml.XmlWriter xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings); 
Serializer.Serialize(xmlWriter, this); 
memoryStream.Seek(0, System.IO.SeekOrigin.Begin); 
streamReader = new System.IO.StreamReader(memoryStream); 
return streamReader.ReadToEnd(); 
} 

和此對象(從xsd2code gen之類):

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.225")] 
[System.SerializableAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "Com.Foo.Request")] 
[System.Xml.Serialization.XmlRootAttribute(Namespace = "Com.Foo.Request", IsNullable = false)] 
public partial class REQUEST_GROUP 
{ 

[EditorBrowsable(EditorBrowsableState.Never)] 
private List<REQUESTING_PARTY> rEQUESTING_PARTYField; 

[EditorBrowsable(EditorBrowsableState.Never)] 
private RECEIVING_PARTY rECEIVING_PARTYField; 

[EditorBrowsable(EditorBrowsableState.Never)] 
private SUBMITTING_PARTY sUBMITTING_PARTYField; 

[EditorBrowsable(EditorBrowsableState.Never)] 
private REQUEST rEQUESTField; 

[EditorBrowsable(EditorBrowsableState.Never)] 
private string iDField; 

public REQUEST_GROUP() 
{ 
    this.rEQUESTField = new REQUEST(); 
    this.sUBMITTING_PARTYField = new SUBMITTING_PARTY(); 
    this.rECEIVING_PARTYField = new RECEIVING_PARTY(); 
    this.rEQUESTING_PARTYField = new List<REQUESTING_PARTY>(); 
    this.IDField = "2.1"; 
} 
} 

輸出從序列化使用UTF-8的編碼:

<?xml version="1.0" encoding="utf-8"?> <REQUEST_GROUP xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ID="2.1" xmlns="Com.Foo.Request"> <RECEIVING_PARTY /> <SUBMITTING_PARTY /> <REQUEST LoginAccountIdentifier="xxx" LoginAccountPassword="yyy" _RecordIdentifier="" _JobIdentifier=""> <REQUESTDATA> <PROPERTY_INFORMATION_REQUEST _SpecialInstructionsDescription="" _ActionType="Submit"> <_DATA_PRODUCT _ShortSubjectReport="Y" /> <_PROPERTY_CRITERIA _City="Sunshine City" _StreetAddress2="" _StreetAddress="123 Main Street" _State="CA" _PostalCode="12345"> <PARSED_STREET_ADDRESS /> </_PROPERTY_CRITERIA> <_SEARCH_CRITERIA /> <_RESPONSE_CRITERIA /> </PROPERTY_INFORMATION_REQUEST> </REQUESTDATA> </REQUEST> </REQUEST_GROUP>

編輯 問題1:如何以這種方式修飾類,或者在處理期間操縱序列化程序來擺脫REQUEST_GROUP節點中的所有命名空間,而不是使用xslt或regex進行後處理。

問題2:如果您也可以添加文檔類型,則爲獎勵點。

謝謝。

回答

2

如果你只是想刪除的名稱空間別名,那麼作爲已經顯示出可以使用XmlSerializerNamespaces強制XmlSerializer使用的名稱空間明確(即xmlns="blah")每個元素上,而不是定義別名,並使用別名。

但是,不管你用別名做什麼,該元素的名稱根本就是REQUEST_GROUPCom.Foo.Request命名空間。你不能刪除命名空間完全而沒有代表對底層數據的重大改變 - 即某個人某處將會得到一個異常(由於獲取了它沒有想到的數據 - 特別是在根名稱空間中的REQUEST_GROUP)。在C#方面,它是System.StringMy.Custom.String之間的差異 - 當然,它們都被稱爲String,但這只是它們的本地名稱。

如果你想刪除命名空間的所有痕跡,然後以務實的辦法是從[XmlRoot(...)][XmlType(...)]編輯掉Namespace=...項(加上其他地方未示例中所示)。

如果類型是你的控制之外,還可以使用XmlAttributeOverrides做到這一點在運行時 - 但一個警告:如果你創建一個XmlSerializer使用XmlAttributeOverrides必須緩存和重新使用它 - 否則你AppDomain將會泄漏(它在此模式下在每個串行器上運行時創建組件,並且組件不能卸載)。

6

您可以刪除的命名空間是這樣的:

XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
ns.Add(string.Empty, string.Empty); 
ns.Add(string.Empty, "Com.Foo.Request"); 
Serializer.Serialize(xmlWriter, this, ns); 

,作爲添加的doctype,我知道這是可能使一個自定義XmlWriter,只是覆蓋WriteStartDocument有說對WriteDocType呼叫的方法,但我有人希望別人知道比這更簡單的方法。

編輯:通過調用Dispose方法的塊結束時

using(System.Xml.XmlWriter xmlWriter = XmlWriter.Create(etc.)) 
{ 
    // use it here. 
} 

它自動處理整理的流:順便提及,強烈建議使用using

+0

@ Flynn1179 - 刪除了大部分命名空間,但在REQUEST_GROUP中仍然存在xmlns:q1 =「Com.Foo.Request」,作爲副產品,所有節點的前綴都是 2011-05-17 23:06:50

+0

我看不到在問題中對'q1'命名空間的任何引用......來自哪裏? – Flynn1179 2011-05-18 06:17:47

+0

@ Flynn1179 - 它發生在我運行你的建議之後.. – 2011-05-18 14:31:09