4 Stimmen

Namensräume während der XML-Serialisierung entfernen

Angesichts dieses generischen Serialisierungscodes:

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();
}

und dieses Objekt (generiert aus xsd2code):

[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";
 }
}

Ausgabe von Serialize mit einer Kodierung von 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>

EDITAR Frage 1: Wie dekoriere ich die Klasse auf diese Weise oder manipuliere den Serializer, um alle Namespaces im REQUEST_GROUP-Knoten während der Verarbeitung loszuwerden, NICHT bei der Nachbearbeitung mit xslt oder regex.

Frage 2: Bonuspunkt, wenn Sie auch den Dokumenttyp hinzufügen könnten.

Ich danke Ihnen.

7voto

Flynn1179 Punkte 11757

Sie können die Namespaces wie folgt entfernen:

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

Was das Hinzufügen des Doctype betrifft, weiß ich, dass es möglich ist, eine benutzerdefinierte XmlWriter und einfach außer Kraft setzen WriteStartDocument mit einer Methode, die einen Aufruf an WriteDocType aber ich hoffe, dass jemand anderes einen einfacheren Weg kennt als diesen.

EDIT: Im Übrigen empfehle ich dringend die Verwendung von using :

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

Es sorgt automatisch für das Aufräumen der Streams, indem es die Dispose Methode, wenn der Block endet.

0 Stimmen

@Flynn1179 - die meisten Namespaces wurden entfernt, ABER es gibt immer noch xmlns:q1="Com.Foo.Request" in der REQUEST_GROUP, und als Nebenprodukt wird allen Knoten ein <q1:xxx vorangestellt

0 Stimmen

Ich sehe keinen Hinweis auf eine q1 Namensraum in der Frage woher kommt das?

1 Stimmen

@SPATEN, um dies zu beheben, fügen Sie auch ns.Add("", "Com.Foo.Request"); - dann ist der Namespace ohne Alias.

4voto

Marc Gravell Punkte 970173

Wenn Sie nur den Namespace entfernen wollen Aliasnamen dann können Sie, wie bereits gezeigt, mit XmlSerializerNamespaces zu erzwingen XmlSerializer den Namensraum zu verwenden ausdrücklich (d.h. xmlns="blah" ) für jedes Element, anstatt einen Alias zu deklarieren und stattdessen den Alias zu verwenden.

Unabhängig davon, was Sie mit den Aliasen machen, ist der grundlegende Name dieses Elements jedoch REQUEST_GROUP im Com.Foo.Request Namensraum . Sie können den Namespace nicht entfernen vollständig ohne dass dies eine einschneidende Änderung der zugrundeliegenden Daten bedeutet - d.h. irgendwo wird es zu einer Ausnahme kommen (weil es Daten erhält, die es nicht erwartet hat - speziell REQUEST_GROUP im Root-Namensraum). In C# ausgedrückt, ist es der Unterschied zwischen System.String y My.Custom.String - Sicher, sie heißen beide String aber das ist nur ihre . Name.

Wenn Sie wollen um alle Spuren des Namensraums zu entfernen, wäre eine pragmatische Option, die Datei Namespace=... Einträge von [XmlRoot(...)] y [XmlType(...)] (und an allen anderen Stellen, die nicht in dem Beispiel gezeigt werden).

Wenn die Typen außerhalb Ihrer Kontrolle liegen, können Sie dies auch zur Laufzeit tun, indem Sie XmlAttributeOverrides - aber ein Vorbehalt: Wenn Sie eine XmlSerializer mit XmlAttributeOverrides Sie muss Cache und verwenden Sie ihn wieder - sonst wird Ihr AppDomain undicht wird (es erstellt Baugruppen im laufenden Betrieb per Serialisierer in diesem Modus, und Baugruppen kann nicht entladen werden).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X