如何在序列化之前将命名空间添加到 XML

How to add namespaces to XML before serialization

我对命名空间的序列化有疑问。正如我的代码在下面显示的那样,我的逻辑填充了我的字典的结构,将其序列化并放入一个字符串变量中。我使用此变量加载到 XMLDocument 中,然后添加名称空间。但是因为它们是在序列化过程之后添加的,所以命名空间是在 UTF8 中设置的吗?我应该在序列化之前添加名称空间吗?如果是,我该如何正确操作?

///Dictionary
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace TestXML
{
[Serializable]
[XmlRoot(ElementName = "Root")]
public class XMLSchema: Serialization
{
    [XmlElement(ElementName = "Element1")]
    public XMLElement1 Element1 { get; set; }

    [XmlElement(ElementName = "Element2")]
    public XMLElement2 Element2 { get; set; }

}
}


 ///Serialization class
 public class Utf8StringWriter : StringWriter
    {
        // Use UTF8 encoding 
        public override Encoding Encoding
        {
            get { return new UTF8Encoding(false); } 
        }
    }

    public string Serialize()
    {
        var xmlserializer = new XmlSerializer(this.GetType());
        var Utf8StringWriter = new Utf8StringWriter();
        var xns = new XmlSerializerNamespaces();
        xns.Add(string.Empty, string.Empty);

        using (var writer = XmlWriter.Create(Utf8StringWriter))
        {
            xmlserializer.Serialize(writer, this, xns);
          return Utf8StringWriter.ToString();
        }
    }


    ///create xml
            str xml;
            [...] my logic to add data into elements
            XmlDocument doc = new XmlDocument();
            xml = XMLSchema.Serialize();

            doc.LoadXml(xml);
            
            XmlElement root = doc.getNamedElement("Root");
            root.SetAttribute("xmlns:etd", "http://google.com");
            root.SetAttribute("xmlns:xsi", "http://google.com");
            root.SetAttribute("xmlns", "http://google.com");
            doc.AppendChild(root);

            doc.Save(path);

编辑。添加提供的示例。

<?xml version="1.0" encoding="UTF-8"?>    <XMLSample xmlns="http://crd.gov.pl/wzor/" xmlns:xsi="http://www.w3.org/2001/" xmlns:etd="http://crd.gov.pl/xml/schematy/">

所以给你举个例子(基于你的样本):

[XmlRoot("XMLSample", Namespace = "http://crd.gov.pl/wzor/")]
public class XmlSample
{
    [XmlElement]
    public string Element1 { get; set; }

    [XmlElement(Namespace = "http://crd.gov.pl/xml/schematy/")]
    public string Element2 { get; set; }
}

这里,根有命名空间http://crd.gov.pl/wzor/Element1 继承了该命名空间(因为指定了 none)。 Element2 具有命名空间 http://crd.gov.pl/xml/schematy/.

序列化时,序列化程序将默认使用根命名空间,因此无需显式设置。您可以将其他人设置为使用示例中定义的前缀:

var xsn = new XmlSerializerNamespaces();
xsn.Add("xsi", "http://www.w3.org/2001/");
xsn.Add("etd", "http://crd.gov.pl/xml/schematy/");

你可以看this fiddle一个demo,输出是:

<?xml version="1.0" encoding="utf-8"?>
<XMLSample xmlns:xsi="http://www.w3.org/2001/" xmlns:etd="http://crd.gov.pl/xml/schematy/" xmlns="http://crd.gov.pl/wzor/">
  <Element1>foo</Element1>
  <etd:Element2>bar</etd:Element2>
</XMLSample>

请注意 Element2 使用为其命名空间配置的前缀。