【问题标题】:XML namespaces for sub class in c#c#中子类的XML命名空间
【发布时间】:2015-04-11 04:14:31
【问题描述】:

我需要使用序列化程序创建具有特定外观的 xml:

                EPIT11V21 curpit11 = new EPIT11V21(curdec.id);

                XmlSerializer serializer = new XmlSerializer(typeof(EPIT11V21));
                using (TextWriter writer = new StreamWriter(@"F:\xml\Xml.xml"))
                {
                    serializer.Serialize(writer, curpit11);
                }

我的 EPIT11V21 类的声明位置:

[XmlRoot("Deklaracja")]
public class EPIT11V21
{
     public EPIT11V21()        {        }

    public EPIT11V21(int XPDeclarationID)
    {
            this.Pouczenie = "Za uchybienie obowiązkom płatnika grozi odpowiedzialność przewidziana w Kodeksie karnym skarbowym.";
            //this.Zalaczniki = "";
        }

    }

    public Podmiot1PIT11V21 Podmiot1 = new Podmiot1PIT11V21();
    public String Pouczenie { get; set; }
    public String Zalaczniki{ get; set; }

带有子类:

public class Podmiot1PIT11V21
{
    public Podmiot1PIT11V21(){}
    [XmlAttribute("rola")]
    public string rola = "Płatnik";
    public OsobaNiefizycznaPIT11V21 OsobaNieFizyczna = new OsobaNiefizycznaPIT11V21();
}


public class OsobaNiefizycznaPIT11V21
{
    public OsobaNiefizycznaPIT11V21(){}
    public string NIP = "0000000000";
    public string PelnaNazwa = "XXXXXXXX";
}

如何装饰它的零件以获得这样的效果:

<?xml version="1.0" encoding="UTF-8"?>
<Deklaracja xsi:schemaLocation="http://crd.gov.pl/wzor/2014/12/08/1887/ http://crd.gov.pl/wzor/2014/12/08/1887/schemat.xsd" xmlns="http://crd.gov.pl/wzor/2014/12/08/1887/" xmlns:etd="http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2011/06/21/eD/DefinicjeTypy/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:zzu="http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2011/10/07/eD/ORDZU/">
    <Podmiot1 rola="Płatnik">
        <etd:OsobaNiefizyczna>
            <etd:NIP>0000000000</etd:NIP>
            <etd:PelnaNazwa>XXXXXXXXXXXXX</etd:PelnaNazwa>
        </etd:OsobaNiefizyczna>
    </Podmiot1>
    <Zalaczniki>
    </Zalaczniki>
</Deklaracja>

我刚进入第二行:

<Deklaracja xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

还有如何装饰该类以获得 etd: 前缀,如示例中所示??

【问题讨论】:

    标签: c# xml


    【解决方案1】:

    您的问题有很多不同的组成部分:

    1. 为了使属性OsobaNiefizyczna进入正确的命名空间,用XmlElement装饰它并正确设置Namespace属性。

    2. 为了向根文档对象添加额外的命名空间,请将[XmlNamespaceDeclarations] 属性附加到返回命名空间的public XmlSerializerNamespaces xmlsn 合成属性。还要在根对象上正确设置XmlRootAttribute.Namespace

    3. 要使根对象具有schemaLocation 属性,您必须按照How to add xsi schemalocation to root c # object XmlSerializer 中的答案添加合成属性——但使用属性而不是字段。如果你使用一个字段,你实际上会添加到你的类在内存中的足迹。

    4. 要省略标准的 xsd 命名空间(尽管我建议您不要这样做),请使用 XmlSerializer.Serialize(XmlWriter, Object, XmlSerializerNamespaces) 方法并仅传入您想要查看的命名空间。

    5. 要显示一个空的Zalaczniki 元素,您需要将属性值设置为string.Empty

    把这些放在一起,我们得到:

    public static class NameSpaces
    {
        static readonly XmlSerializerNamespaces namespaces;
    
        static NameSpaces()
        {
            namespaces = new XmlSerializerNamespaces();
            namespaces.Add("", NameSpaces.Default);
            namespaces.Add("xsi", NameSpaces.Xsi);
            namespaces.Add("etd", NameSpaces.Etd);
            namespaces.Add("zzu", NameSpaces.Zzu);
        }
    
        public static XmlSerializerNamespaces XmlSerializerNamespaces
        {
            get
            {
                return namespaces;
            }
        }
    
        public const string Default = "http://crd.gov.pl/wzor/2014/12/08/1887/";
        public const string Etd = "http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2011/06/21/eD/DefinicjeTypy/";
        public const string Xsi = "http://www.w3.org/2001/XMLSchema-instance";
        public const string Zzu = "http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2011/10/07/eD/ORDZU/";
        public const string SchemaLocation = "http://crd.gov.pl/wzor/2014/12/08/1887/ http://crd.gov.pl/wzor/2014/12/08/1887/schemat.xsd";
    }
    
    [XmlRoot("Deklaracja", Namespace = NameSpaces.Default)]
    public class EPIT11V21
    {
        public EPIT11V21() {
            this.Zalaczniki = string.Empty;
        }
    
        public EPIT11V21(int XPDeclarationID) : this()
        {
            this.Pouczenie = "Za uchybienie obowiązkom płatnika grozi odpowiedzialność przewidziana w Kodeksie karnym skarbowym.";
        }
    
        [XmlAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
        public string XSDSchemaLocation
        {
            get
            {
                return NameSpaces.SchemaLocation;
            }
            set {
                // Do nothing - fake property.
            }
        }
    
        public Podmiot1PIT11V21 Podmiot1 = new Podmiot1PIT11V21();
    
        public String Pouczenie { get; set; }
    
        public String Zalaczniki { get; set; }
    
        [XmlNamespaceDeclarations]
        public XmlSerializerNamespaces xmlsn
        {
            get
            {
                return NameSpaces.XmlSerializerNamespaces;
            }
            set { 
                // Do nothing - fake property.
            }
        }
    }
    
    public class Podmiot1PIT11V21
    {
        public Podmiot1PIT11V21() { }
    
        [XmlAttribute("rola")]
        public string rola = "Płatnik";
    
        [XmlElement("OsobaNieFizyczna", Namespace = NameSpaces.Etd)]
        public OsobaNiefizycznaPIT11V21 OsobaNieFizyczna = new OsobaNiefizycznaPIT11V21();
    }
    
    public class OsobaNiefizycznaPIT11V21
    {
        public OsobaNiefizycznaPIT11V21() { }
        public string NIP = "0000000000";
        public string PelnaNazwa = "XXXXXXXX";
    }
    

    并且,测试:

    public static class TestClass
    {
        public static void Test()
        {
            var curpit11 = new EPIT11V21(10101);
    
            var xml = XmlSerializationHelper.GetXml(curpit11, NameSpaces.XmlSerializerNamespaces);
            Debug.WriteLine(xml);
        }
    }
    
    public static class XmlSerializationHelper
    {
        public static string GetXml<T>(this T obj)
        {
            return GetXml(obj, false);
        }
    
        public static string GetXml<T>(this T obj, bool omitNamespace)
        {
            return GetXml(obj, new XmlSerializer(obj.GetType()), omitNamespace);
        }
    
        public static string GetXml<T>(this T obj, XmlSerializer serializer)
        {
            return GetXml(obj, serializer, false);
        }
    
        public static string GetXml<T>(T obj, XmlSerializer serializer, bool omitStandardNamespaces)
        {
            XmlSerializerNamespaces ns = null;
            if (omitStandardNamespaces)
            {
                ns = new XmlSerializerNamespaces();
                ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
            }
            return GetXml(obj, serializer, ns);
        }
    
        public static string GetXml<T>(T obj, XmlSerializerNamespaces ns)
        {
            return GetXml(obj, new XmlSerializer(obj.GetType()), ns);
        }
    
        public static string GetXml<T>(T obj, XmlSerializer serializer, XmlSerializerNamespaces ns)
        {
            using (var textWriter = new StringWriter())
            {
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Indent = true;        // For cosmetic purposes.
                settings.IndentChars = "    "; // For cosmetic purposes.
                using (var xmlWriter = XmlWriter.Create(textWriter, settings))
                {
                    if (ns != null)
                        serializer.Serialize(xmlWriter, obj, ns);
                    else
                        serializer.Serialize(xmlWriter, obj);
                }
                return textWriter.ToString();
            }
        }
    }
    

    生产

    <Deklaracja xmlns:zzu="http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2011/10/07/eD/ORDZU/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:etd="http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2011/06/21/eD/DefinicjeTypy/" xsi:schemaLocation="http://crd.gov.pl/wzor/2014/12/08/1887/ http://crd.gov.pl/wzor/2014/12/08/1887/schemat.xsd" xmlns="http://crd.gov.pl/wzor/2014/12/08/1887/">
        <Podmiot1 rola="Płatnik">
            <etd:OsobaNieFizyczna>
                <etd:NIP>0000000000</etd:NIP>
                <etd:PelnaNazwa>XXXXXXXX</etd:PelnaNazwa>
            </etd:OsobaNieFizyczna>
        </Podmiot1>
        <Pouczenie>Za uchybienie obowiązkom płatnika grozi odpowiedzialność przewidziana w Kodeksie karnym skarbowym.</Pouczenie>
    <Zalaczniki />
    </Deklaracja>
    

    【讨论】:

    • 感谢您的快速响应,我将对其进行测试。还有一个问题,我不知道良好的 xml 构建,如何更改该代码以具有 Deklaracja 的属性顺序,就像我在示例中给出的那样。在您的输出中,它们的顺序不同。
    • 据我所知,您无法使用XmlSerializer 控制命名空间属性的顺序。但是,根据XML specification Section 3.1,“开始标签或空元素标签中属性规范的顺序并不重要。”。所以应该没关系。但是,如果您必须具有特定顺序的属性(出于政治原因?),您可能必须将 XML 重新加载到 XDocument 并遵循此处的算法:stackoverflow.com/questions/28420906/…
    【解决方案2】:

    我像这样更改我的代码:

                Declaration curdec = gVDeclarations.GetRow(i) as Declaration;
                EPIT11V21 curpit11 = new EPIT11V21(curdec.id);
    
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    
                ns.Add("schemaLocation", @"http://crd.gov.pl/wzor/2014/12/08/1887/ http://crd.gov.pl/wzor/2014/12/08/1887/schemat.xsd");
                ns.Add("xmlns", @"http://crd.gov.pl/wzor/2014/12/08/1887/");
                ns.Add("etd", @"http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2011/06/21/eD/DefinicjeTypy/");
                ns.Add("xsi", @"http://www.w3.org/2001/XMLSchema-instance");
                ns.Add("zzu", @"http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2011/10/07/eD/ORDZU/");
    
                XmlSerializer serializer = new XmlSerializer(typeof(EPIT11V21));
                using (TextWriter writer = new StreamWriter(@"F:\xml\Xml.xml"))
                {
                    serializer.Serialize(writer, curpit11,ns);
                }
    

    和 Deklaracja 子类

    public class Podmiot1PIT11V21
    {
        public Podmiot1PIT11V21(){}
        [XmlAttribute("rola")]
        public string rola = "Płatnik";
        [XmlElement("OsobaNieFizyczna", Namespace = "http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2011/06/21/eD/DefinicjeTypy/")]
        public OsobaNiefizycznaPIT11V21 OsobaNieFizyczna = new OsobaNiefizycznaPIT11V21();
    }
    

    我得到了我想要的,但我得到的第二行:

        <Deklaracja 
    xmlns:xmlns="http://crd.gov.pl/wzor/2014/12/08/1887/" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:schemaLocation="http://crd.gov.pl/wzor/2014/12/08/1887/ http://crd.gov.pl/wzor/2014/12/08/1887/schemat.xsd" 
    xmlns:zzu="http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2011/10/07/eD/ORDZU/" 
    xmlns:etd="http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2011/06/21/eD/DefinicjeTypy/">
    

    有没有办法只更改“ns”以轻松更改该行?

    【讨论】:

    • schemaLocation 不是命名空间。您不能使用XmlSerializerNamespaces 添加它。见这里:stackoverflow.com/questions/27530334/…
    • 另外,建议咨询one question per question。如果您在对自己问题的自我回答中提出第二个问题,很少有人会注意到。
    • 建议您避免在代码中重复长字符串常量。 NameSpaces 静态类旨在集中它们。
    • 感谢您提供的信息,我在这里有点新意 :)。您能否添加更多代码以完成如何使用您创建的静态类。 (主要功能)我是编程新手,有些事情我不知道(或者我不确定我是否做对了,如果我做对了,你的例子应该是:Testclass.Test(); 对吗?
    • 我编辑了我的答案以分离出一个 XmlSerializationHelper 类,该类生成具有指定命名空间的格式化 XML。一旦分配了EPIT11V21,然后调用那里的方法。不知道你还需要什么。
    猜你喜欢
    • 1970-01-01
    • 2010-11-21
    • 1970-01-01
    • 2010-11-24
    • 2013-02-22
    • 2016-02-09
    • 2020-03-04
    • 2012-05-05
    • 1970-01-01
    相关资源
    最近更新 更多