我必须创建一个前缀为所有元素的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);
}
答案 0 :(得分:15)
首先,如果您的字符串的使用者正在处理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类,但仍然返回包含为UTF-8编写的XML的字符串。
最后,要控制前缀,请参阅"How to: Qualify XML Element and XML Attribute Names":
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());
}
答案 1 :(得分:0)
另请查看XmlNamespaceDeclarationsAttribute。警告:反序列化时只会为您提供由该元素定义的名称空间,它不会在父元素中定义名称空间。如果你没有一致的根类型,那么使用@John Saunders的XmlSerializer.Serialize()重载。
在另一个问题中,@ John Saunders建议在WSDL中控制xmlns时使用此属性:Namespace Prefixes in 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" />