【问题标题】:Generate XML from C# Class with specific attributes从具有特定属性的 C# 类生成 XML
【发布时间】:2013-12-04 09:50:53
【问题描述】:

我遇到了一个关于 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>

所有 XMLNS 属性都是必需的,需要通过代码进行配置。我目前得到的输出是:

<?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>

您可以看到包含 prolog 的行不正确,我需要它仅显示第一个 XML 示例中的值。冒号也被转换为x003A,我需要它成为冒号。

这是我目前正在使用的代码,请记住它只是测试代码,字段将在生产前更改。

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;
        }
    }
}

我知道我需要更改 XMLRoot 行以实现所需的输出,但我不确定我需要在这里更改什么?

另外,在写入文件之前,我如何强制保留 COLON 而不是修改为 x003A

最后一个问题,因为我没有填充 R3 和 R4,有没有一种方法可以防止它们被写入 XML,如果没有填充值,类似于 R2 没有写入文件的方式,我相信区别是R2 是一个字符串,而 R3 和 R4 是复杂类型,这使得序列化程序更难以确定是否应该编写它们?

编辑:

在应用 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>

如何更改 xsi 的 d1p1?

另外缺少的一行是 xmlns="http://www.Test.com/MyClass">,我该如何添加呢?

编辑 - 2:

多亏了 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>

并更新了代码:

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;
        }
    }
}

现在唯一的问题是缺少行 xmlns="http://www.Test.com/MyClass">

如果我将以下代码添加到命名空间部分:

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

我得到了我需要的输出,但是如果大小写与命名空间 MyClass 相同,则必须更改其中一个字母的大小写以获取输出,然后它不会输出。

提前致谢

【问题讨论】:

  • 我已将 Ralp 的答案标记为已接受的答案,因为他的更改帮助我获得了 99% 的解决方案。我现在唯一要开始工作的是将 xmlns="Test.com/MyClass"> 添加到文件中

标签: c# .net xml xml-serialization


【解决方案1】:

Namespace 是 MyClass,Elementname 是 Req。 所以你需要定义命名空间。

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

并调用采用 XmlSerializerNamespaces 实例的 Serialize 重载。 Request 类本身就是一个名为 Req 的元素。

[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 可以通过声明为 Xml 属性的属性添加。 如果一个属性应该被序列化,可以通过一个具有 ShouldSerialize*MyLovelyPropertyName()* 语法的方法来控制。

【讨论】:

  • 谢谢拉尔夫,我现在结束了:test.com/myclass.xsd" - 怎么做我删除 d1p1 代替 xsi? xmlns:d1p1="w3.org/2001/XMLSchema-instance" xmlns:MyClass="test.com/myclass"> 010
  • d1p1 是一个伪造的命名空间。如果您想要某个命名空间,请定义它。 ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 可能会有所帮助。也许您还需要添加一个没有名称(空字符串)的命名空间。
  • 或者更好地为 SchemaLocation 定义一个空的命名空间。我将相应地编辑代码。
  • 感谢 Ralf,ns.Add("xsi", "w3.org/2001/XMLSchema-instance"); 修复了 d1p1 的问题,现在唯一遗漏的是 xmlns="Test.com/MyClass">
  • 您是否尝试过添加一个无名(因此希望是默认)命名空间来获取它? ns.Add("", "Test.com/MyClass");
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 2013-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多