XmlSerializer Создание XML без префикса пространства имен - PullRequest
6 голосов
/ 14 мая 2010

Мне нужно создать файл XML со всеми элементами с префиксом, например:

<ps:Request num="123" xmlns:ps="www.ladieda.com">
   <ps:ClientId>5566</ps:ClientId>
<ps:Request>

Когда я сериализую свой объект, c # умен и делает это:

<Request num="123" xmlns="www.ladieda.com">
   <ClientId>5566</ClientId>
<Request>

Это хорошо, потому что ps: не нужен.

Но есть ли способ заставить C # сериализовать все префиксы?

Мой сериализованный код такой (для входящего объекта pObject):

String XmlizedString = null;
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(pObject.GetType());
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

xs.Serialize(xmlTextWriter, pObject);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
return XmlizedString;


private String UTF8ByteArrayToString(Byte[] characters)
{
    UTF8Encoding encoding = new UTF8Encoding();
    String constructedString = encoding.GetString(characters);
    return (constructedString);
}

Ответы [ 2 ]

15 голосов
/ 14 мая 2010

Прежде всего, если бы потребитель вашей строки обрабатывал XML, он бы не заботился о префиксе, поскольку он не имеет значения (для XML). Возможно, они не понимают XML и думают, что обрабатывают строку (для этого может потребоваться строка «ps:» в каждом элементе).

Во-вторых, вы должны немного изменить свой код:

XmlSerializer xs = new XmlSerializer(pObject.GetType());
using (MemoryStream memoryStream = new MemoryStream())
{
    XmlWriterSettings settings = new XmlWriterSettings()
    {
        Encoding = Encoding.UTF8
    };
    using (XmlWriter writer = XmlWriter.Create(memoryStream, settings))
    {
        xs.Serialize(writer, pObject);
    }
    return Encoding.UTF8.GetString(memoryStream.ToArray());
}

Это правильно избавится от потока и XmlWriter, если возникнет исключение, прекратит использование устаревшего класса XmlTextWriter и все же вернет строку, содержащую XML, написанный для UTF-8.

Наконец, для управления префиксом см. «Как: квалифицировать имена элементов XML и атрибутов XML» :

XmlSerializerNamespaces myNamespaces = new XmlSerializerNamespaces();
myNamespaces.Add("ps", "www.ladieda.com");

XmlSerializer xs = new XmlSerializer(pObject.GetType());
using (MemoryStream memoryStream = new MemoryStream())
{
    XmlWriterSettings settings = new XmlWriterSettings()
    {
        Encoding = Encoding.UTF8
    };
    using (XmlWriter writer = XmlWriter.Create(memoryStream, settings))
    {
        xs.Serialize(writer, pObject, myNamespaces);
    }
    return Encoding.UTF8.GetString(memoryStream.ToArray());
}
0 голосов
/ 22 декабря 2011

Также ознакомьтесь с XmlNamespaceDeclarationsAttribute. Предостережение: при десериализации оно даст вам только пространства имен, определенные этим элементом, у него не будет пространств имен, определенных в родительских элементах. Если у вас нет согласованного корневого типа, используйте перегрузку XmlSerializer.Serialize () из @John Saunders.

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlnamespacedeclarationsattribute.aspx

В другом вопросе @John Saunders предлагает использовать этот атрибут в отношении управления xmlns в WSDL: Префиксы пространства имен в Wsdl (.net)

Из MSDN Образец:

// C#
using System;
using System.IO;
using System.Xml.Serialization;
[XmlRoot("select")]
public class Select {
    [XmlAttribute] public string xpath;
    [XmlNamespaceDeclarations] public XmlSerializerNamespaces xmlns;
}
public class Test {
    public static void Main(string[] args) {
       Select mySelect = new Select();
       mySelect.xpath = "myNS:ref/@common:y";
       mySelect.xmlns = new XmlSerializerNamespaces();
       mySelect.xmlns.Add("MyNS", "myNS.tempuri.org");
       mySelect.xmlns.Add("common", "common.tempuri.org");
       XmlSerializer ser = new XmlSerializer(typeof(Select));
       ser.Serialize(Console.Out, mySelect);
    }
}
// Output:
// <?xml version="1.0" encoding="IBM437"?>
// <select xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmln:xsi="http://www.w3.org/2001/XMLSchema-instance" 
// xmlns:common="common.tempuri.org" xmlns:MyNS="myNS.tempuri.org" xpath="myNS:ref/@common:y" />
...