简体   繁体   English

从具有特定属性的C#类生成XML

[英]Generate XML from C# Class with specific attributes

I am stuck with an issue regarding XML serialization of a class in c#: What i Want is the XML in the format below 我遇到了有关C#中类的XML序列化的问题:我想要的是以下格式的XML

<?xml version="1.0" encoding="utf-8"?>
<MyClass:Req xsi:schemaLocation="http://www.Test.com/MyClass.xsd"
            xmlns:TestClass="http://www.Test.com/MyClass" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://www.Test.com/MyClass">
  <head>
    <hA>01</hA>
  </head>
  <body>
    <R1>0</R1>
    <R3 />
    <R4 />
  </body>
</MyClass:Req>

All the XMLNS attributes are required and need to be configure via the code. 所有XMLNS属性都是​​必需的,并且需要通过代码进行配置。 The output i am currently getting is: 我当前得到的输出是:

<?xml version="1.0" encoding="utf-8"?>
<MyClass_x003A_Req xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns="http://www.Test.com/MyClass">
  <head>
    <hA>01</hA>
  </head>
  <body>
    <R1>0</R1>
    <R3 />
    <R4 />
  </body>
</MyClass_x003A_Req>

As you can see the line containing the prolog is incorrect, i need it to show just the values in the first XML example. 如您所见,包含序言的行不正确,我需要它仅显示第一个XML示例中的值。 Also the Colon is transformed to x003A and i need this to be a COLON. 另外,冒号也被转换为x003A ,我需要将其设为冒号。

Here is the code i am using at the moment, bear in mind its just test code the fields are to be changed before production. 这是我目前正在使用的代码,请记住它只是测试代码,这些字段将在生产前进行更改。

request theReq = new request();
requestHead rHead = new requestHead();
requestBody rBody = new requestBody();

rHead.hA = "01";

rBody.R1 = "0";

theReq.head = rHead;
theReq.body = rBody;

XmlSerializer serializer = new XmlSerializer(typeof(request));
TextWriter textWriter = new StreamWriter(@"Test.xml");
serializer.Serialize(textWriter, theReq);
textWriter.Close();




[XmlRoot(Namespace = "http://www.Test.com/MyClass",
    ElementName = "MyClass:Req",
    DataType = "string",
    IsNullable = true)]
public partial class request
{
    private requestHead headField;

    private requestBody bodyField;

    public request()
    {
        this.bodyField = new requestBody();
        this.headField = new requestHead();
    }

    public requestHead head
    {
        get
        {
            return this.headField;
        }
        set
        {
            this.headField = value;
        }
    }

    public requestBody body
    {
        get
        {
            return this.bodyField;
        }
        set
        {
            this.bodyField = value;
        }
    }
}

public partial class requestHead
{
    private string headAField;

    private string headBField;

    public string hA
    {
        get
        {
            return this.headAField;
        }
        set
        {
            this.headAField = value;
        }
    }

    public string hB
    {
        get
        {
            return this.headBField;
        }
        set
        {
            this.headBField = value;
        }
    }
}

public partial class requestBody
{
    private string R1Field;

    private string R2Field;

    private requestBodyR3 R3Field;

    private requestBodyR4 R4Field;

    public requestBody()
    {
        this.R4Field = new requestBodyR4();
        this.R3Field = new requestBodyR3();
    }

    public string R1
    {
        get
        {
            return this.R1Field;
        }
        set
        {
            this.R1Field = value;
        }
    }

    public string R2
    {
        get
        {
            return this.R2Field;
        }
        set
        {
            this.R2Field = value;
        }
    }

    public requestBodyR3 R3
    {
        get
        {
            return this.R3Field;
        }
        set
        {
            this.R3Field = value;
        }
    }

    public requestBodyR4 R4
    {
        get
        {
            return this.R4Field;
        }
        set
        {
            this.R4Field = value;
        }
    }
}

public partial class requestBodyR3
{

    private string R31Field;

    private string R32Field;

    public string R31
    {
        get
        {
            return this.R31Field;
        }
        set
        {
            this.R31Field = value;
        }
    }

    public string R32
    {
        get
        {
            return this.R32Field;
        }
        set
        {
            this.R32Field = value;
        }
    }
}

public partial class requestBodyR4
{
    private string R41Field;

    public string R41
    {
        get
        {
            return this.R41Field;
        }
        set
        {
            this.R41Field = value;
        }
    }
}

I understand that i need to change the XMLRoot line to achive the desired output but i am unsure what i need to change here? 我知道我需要更改XMLRoot行以实现所需的输出,但是我不确定在这里需要更改什么?

Also how do i force the COLON to be preserved and not modified to the x003A before its written to the file. 另外,我如何在将COLON写入文件之前强制保留COLON,而不将其修改为x003A

One final question since i do not populate R3 & R4 is there a way i can prevent them being written to the XML if there values are not populated similar to the way R2 is not written to the file, i believe the difference is that R2 is a string and R3 & R4 are complex types making it more difficult for the serializer to determine if they should be wrote? 最后一个问题,因为我没有填充R3和R4,如果没有填充值,就像没有将R2和R4写入文件一样,我可以防止它们被写入XML,我相信区别是R2是字符串以及R3和R4是复杂类型,使得序列化程序更难确定是否应写入它们?

EDIT: 编辑:

OK after applying Ralp's suggested changes the file now looks like: 应用Ralp的建议更改后,单击确定,该文件现在如下所示:

<?xml version="1.0" encoding="utf-8"?>
<MyClass:Req d1p1:schemaLocation="http://www.test.com/myclass.xsd" 
             xmlns:d1p1="http://www.w3.org/2001/XMLSchema-instance" 
             xmlns:MyClass="http://www.test.com/myclass">
  <head>
    <hA>01</hA>
  </head>
  <body>
    <R1>0</R1>
    <R3 />
    <R4 />
  </body>
</MyClass:Req>

How can I change the d1p1 for xsi? 如何更改xsi的d1p1?

Also the one line that's missing is xmlns="http://www.Test.com/MyClass">, how do i add that in? 另外缺少的一行是xmlns =“ http://www.Test.com/MyClass”>,我该如何添加呢?

EDIT - 2: 编辑-2:

Almost there thanks to Ralp's help, here is the updated file: 几乎有了Ralp的帮助,这是更新的文件:

<?xml version="1.0" encoding="utf-8"?>
<MyClass:Req xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://www.test.com/myclass.xsd" 
             xmlns:MyClass="http://www.test.com/myclass">
  <head>
    <hA>01</hA>
  </head>
  <body>
    <R1>0</R1>
    <R3 />
    <R4 />
  </body>
</MyClass:Req>

And updated CODE: 并更新了CODE:

request theReq = new request();
requestHead rHead = new requestHead();
requestBody rBody = new requestBody();

rHead.hA = "01";

rBody.R1 = "0";

theReq.head = rHead;
theReq.body = rBody;

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
ns.Add("MyClass", "http://www.test.com/myclass");

XmlSerializer serializer = new XmlSerializer(typeof(request));
TextWriter textWriter = new StreamWriter(@"Test.xml");
serializer.Serialize(textWriter, theReq, ns);
textWriter.Close();



[XmlRoot(Namespace = "http://www.test.com/myclass", ElementName = "Req")]
public partial class request
{
    private requestHead headField;

    private requestBody bodyField;

    public request()
    {
        this.bodyField = new requestBody();
        this.headField = new requestHead();
    }

    [XmlAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
    public string xsiSchemaLocation = "http://www.test.com/myclass.xsd";

    [XmlElement("head", Namespace = "")]
    public requestHead head
    {
        get
        {
            return this.headField;
        }
        set
        {
            this.headField = value;
        }
    }

    [XmlElement("body", Namespace = "")]
    public requestBody body
    {
        get
        {
            return this.bodyField;
        }
        set
        {
            this.bodyField = value;
        }
    }
}

public partial class requestHead
{
    private string headAField;

    private string headBField;

    public string hA
    {
        get
        {
            return this.headAField;
        }
        set
        {
            this.headAField = value;
        }
    }

    public string hB
    {
        get
        {
            return this.headBField;
        }
        set
        {
            this.headBField = value;
        }
    }
}

public partial class requestBody
{
    private string R1Field;

    private string R2Field;

    private requestBodyR3 R3Field;

    private requestBodyR4 R4Field;

    public requestBody()
    {
        this.R4Field = new requestBodyR4();
        this.R3Field = new requestBodyR3();
    }

    public string R1
    {
        get
        {
            return this.R1Field;
        }
        set
        {
            this.R1Field = value;
        }
    }

    public bool ShouldSerializeR1() { return !String.IsNullOrEmpty(R1); }

    public string R2
    {
        get
        {
            return this.R2Field;
        }
        set
        {
            this.R2Field = value;
        }
    }

    public bool ShouldSerializeR2() { return !String.IsNullOrEmpty(R2); }

    public requestBodyR3 R3
    {
        get
        {
            return this.R3Field;
        }
        set
        {
            this.R3Field = value;
        }
    }

    public bool ShouldSerializeR3() { return requestBodyR3.ShouldSerializeRequestBodyR3(); }

    public requestBodyR4 R4
    {
        get
        {
            return this.R4Field;
        }
        set
        {
            this.R4Field = value;
        }
    }
}

public partial class requestBodyR3
{

    private string R31Field;

    private string R32Field;

    public static bool ShouldSerializeRequestBodyR3()
    {
        bool blnRetVal = false;

        //Add code to test these values later

        return blnRetVal;
    }

    public string R31
    {
        get
        {
            return this.R31Field;
        }
        set
        {
            this.R31Field = value;
        }
    }

    public string R32
    {
        get
        {
            return this.R32Field;
        }
        set
        {
            this.R32Field = value;
        }
    }
}

public partial class requestBodyR4
{
    private string R41Field;

    public string R41
    {
        get
        {
            return this.R41Field;
        }
        set
        {
            this.R41Field = value;
        }
    }
}

The only problem now is the lack of the line xmlns="http://www.Test.com/MyClass"> 现在唯一的问题是缺少xmlns =“ http://www.Test.com/MyClass”>

If i add the following code to the namespace section: 如果我将以下代码添加到名称空间部分:

ns.Add("", "http://www.test.com/Myclass");

I get the output i require but NOTICEi jhad to change the case on one of the letters to get the output if the case is the same as the namespace MyClass then it does not output. 如果大小写与名称空间MyClass相同,我会得到我需要的输出,但是NOTICEi不得不改变字母之一的大小写以获取输出,然后它就不会输出。

Thanks In Advance 提前致谢

The Namespace is MyClass and the Elementname is Req. 命名空间为MyClass,元素名称为Req。 So you need to define the Namespace. 因此,您需要定义命名空间。

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();            
ns.Add("MyClass", "http://www.test.com/myclass");

and call a Serialize overload that takes an XmlSerializerNamespaces instance. 并调用带有XmlSerializerNamespaces实例的Serialize重载。 The Request class itself is then an Element named Req. 然后,Request类本身就是一个名为Req的Element。

[XmlRoot(Namespace = "http://www.test.com/myclass", ElementName = "Req")]
public class Request
{
    [XmlElement("R1", Namespace = "")]
    public string R1 { get; set; }
    public bool ShouldSerializeR1()  { return !string.IsNullOrWhiteSpace(R1); }

    [XmlAttribute("schemaLocation", Namespace = "")]
    public string xsiSchemaLocation = "http://www.test.com/myclass.xsd";
}

schemaLocation can be added via a Property declared as a Xml Attribute. 可以通过声明为Xml属性的属性来添加schemaLocation。 If a property should be serialize can be controlled by a method with a ShouldSerialize*MyLovelyPropertyName()* syntax. 可以通过使用ShouldSerialize * MyLovelyPropertyName()*语法的方法来控制是否应序列化属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM