我正在寻找一种使用C#的方法,我可以将类序列化为XML并添加命名空间,但是定义该命名空间将使用的前缀。
最终我正在尝试生成以下XML:
<myNamespace:Node xmlns:myNamespace="...">
<childNode>something in here</childNode>
</myNamespace:Node>
我知道同时使用DataContractSerializer
和XmlSerializer
我可以添加命名空间,但它们似乎在内部生成了一个前缀,我无法控制。我可以使用这些序列化程序控制它(我可以使用其中任何一个)吗?
如果我无法控制命名空间的生成,我是否需要编写自己的XML序列化程序,如果是,那么编写它的最佳方法是什么?
答案 0 :(得分:99)
要控制命名空间别名,请使用XmlSerializerNamespaces
。
[XmlRoot("Node", Namespace="http://flibble")]
public class MyType {
[XmlElement("childNode")]
public string Value { get; set; }
}
static class Program
{
static void Main()
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("myNamespace", "http://flibble");
XmlSerializer xser = new XmlSerializer(typeof(MyType));
xser.Serialize(Console.Out, new MyType(), ns);
}
}
如果您需要在运行时更改名称空间,您还可以使用XmlAttributeOverrides
。
答案 1 :(得分:3)
当使用类型具有命名空间的模式生成的代码时,此命名空间覆盖适用于根级别,但不同类型的标记将具有与该类关联的命名空间。
我有机会需要使用两个不同的生成类,但根据我正在与之交谈的服务器具有不同的名称空间(不要求不在我的控制之下)。
我尝试了这里提供的所有覆盖,最后放弃并使用了一种实际上非常好的蛮力方法。我所做的是序列化为一个字符串。然后使用string.replace更改名称空间,然后使用字符串编写器从字符串中发布流。响应相同 - 捕获到字符串 - 操作命名空间,然后从字符串编写器反序列化字符串。
它可能不优雅或使用所有花哨的覆盖,但它完成了工作。
答案 2 :(得分:1)
我从another thread到达这里,看上去“重复”,但我认为不是。
我在那里回答了,但不是很清晰,所以让我在这里再次回答。
如果您的目标是这样做:
<sample xmlns:sample="urn:sample:ns">
<something>value<something>
<sample:somethingelse>value2</sample:somethingelse>
<new_root xmlns:newns="url:new:ns">
<newns:item1>sample1</newns:item1>
</new_root>
</sample>
我确实为您找到了解决方案:)。
您需要做的是在“ new_root”类中添加这样的名称空间声明。
[XmlNamespaceDeclarations]
public XmlSerializerNamespaces newns;
并在您的item1类中添加以下修饰以便使用您的命名空间
[XmlElement("item1", Namespace = "url:new:ns")]