2010-02-26 133 views
49

我正在寻找一种C#方法,我可以将一个类序列化为XML并添加一个名称空间,但定义该名称空间将使用的前缀。XML序列化和命名空间前缀

最后我想生成以下XML:

<myNamespace:Node xmlns:myNamespace="..."> 
    <childNode>something in here</childNode> 
</myNamespace:Node> 

我知道有两个DataContractSerializerXmlSerializer我可以添加一个命名空间,但他们似乎在内部生成一个前缀,用的东西,我无法控制。我能够用这些序列化器中的任何一个来控制它(我可以使用它们中的任何一个)?

如果我无法控制名称空间的生成,那么我是否需要编写自己的XML序列化程序,如果是,那么最适合写入它的是什么?

回答

84

要控制名称空间别名,请使用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

+4

+1但我可以建议一个编辑,以清楚说明.Add方法中的第一个参数是魔术在设置前缀时发生的地方。直到我检查了MSDN文档之前,我从答案中不清楚。 – 2010-02-26 06:18:20

+0

公平地假设DataContractSerializer没有等价物? (只是想保持我的选择开放) – 2010-02-26 06:30:51

+0

@Slace - 是的,我相信可以肯定的是,**不是**的等价物。最终,DCS不打算让你对输出进行很多控制(如果你想控制xml,使用'XmlSerializer' - 这是它的工作)。 – 2010-02-26 07:08:58

3

当从类型具有名称空间的模式使用生成的代码时,该名称空间覆盖适用于根级别,但不同类型中的标签将具有与该类相关的名称空间。

我有一次需要使用两个不同的生成类,但根据我与之交谈的服务器有不同的名称空间(不要问我不在我的控制下)。

我尝试了所有这里提供的覆盖,最后放弃了,并使用了一种实际工作得很好的蛮力方法。我所做的是序列化为一个字符串。然后使用string.replace来更改命名空间,然后使用字符串打印机从字符串中发布流。响应相同 - 捕获到字符串 - 操作命名空间,然后从字符串编写器反序列化字符串。

它可能不够优雅或使用所有的幻想覆盖,但它完成了工作。