简体   繁体   English

XmlSerializer产生没有命名空间前缀的XML

[英]XmlSerializer Producing XML With No Namespace Prefix

I have to create an XML file with all the elements prefixed, like this: 我必须创建一个带有所有元素前缀的XML文件,如下所示:

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

When i serialize my object, c# is smart and does this: 当我序列化对象时,C#很聪明,并且可以做到这一点:

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

That is good, because the ps: is not necessary. 很好,因为ps:是不必要的。

But is there a way to force C# to serialize all the prefixes? 但是,是否有一种方法可以强制C#序列化所有前缀?

My serialize code is this (for incoming object pObject): 我的序列化代码是这样的(对于传入对象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);
}

First of all, if the consumer of your string were processing XML, then they wouldn't care about the prefix, since it doesn't matter (to XML). 首先,如果字符串的使用者正在处理XML,那么他们将不会在乎前缀,因为它对XML无关紧要。 Perhaps they don't understand XML, and think they're processing a string (which might need to have the string "ps:" on every element). 也许他们不了解XML,并认为他们正在处理一个字符串(可能需要在每个元素上使用字符串“ ps:”)。

Second of all, you should change your code a bit: 第二,您应该对代码进行一些更改:

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

This will properly dispose of the stream and XmlWriter if an exception is thrown, stops using the deprecated XmlTextWriter class, and yet still returns a string containing XML written for UTF-8. 如果抛出异常,这将正确处理流和XmlWriter,停止使用不推荐使用的XmlTextWriter类,但仍返回包含为UTF-8编写的XML的字符串。

Finally, to control the prefix, see "How to: Qualify XML Element and XML Attribute Names" : 最后,要控制前缀,请参阅“如何:限定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());
}

Also check out XmlNamespaceDeclarationsAttribute. 还要检查XmlNamespaceDeclarationsAttribute。 Caveat: when deserializing it will only give you namespaces defined by that element, it won't have namespaces defined in parent elements. 注意:反序列化时,只会为您提供该元素定义的名称空间,而不会在父元素中定义名称空间。 If you don't have a consistent root type then use the XmlSerializer.Serialize() overload from @John Saunders. 如果您没有一致的根类型,请使用@John Saunders的XmlSerializer.Serialize()重载。

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

In another question @John Saunders suggests using this attribute in regards to controlling xmlns in WSDL: Namespace Prefixes in Wsdl (.net) 在另一个问题中,@ John Saunders建议在控制WSDL中的xmlns时使用此属性: Wsdl(.net)中的命名空间前缀。

From MSDN Sample: 从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" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM