C#XmlSerializer使用xs:string以外的类型忽略xs:attribute

时间:2011-02-09 13:35:01

标签: c# attributes xmlserializer

我的问题似乎很奇怪,我没有找到任何其他问题,所以我想这是一个非常简单和愚蠢的错误,我似乎无法找到。

我有一个XSD,我使用xsd.exe生成一个类结构。我使用值“填充”我的对象,但在将其序列化为XML时,它会忽略所有不属于string类型的类属性。

var myGraph = new graph();
myGraph.myString = "hallo";
myGraph.myInt = 80;

var serializer = new XmlSerializer(typeof(graph));
TextWriter writeFileStream = new StreamWriter(Path.Combine(outFolder, outFile));
serializer.Serialize(writeFileStream, myGraph);
writeFileStream.Close();

我期待:

<graph xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
    myString="hallo" 
    myInt="80"
/>

实际输出是:

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

属性myInt已被忽略。如果我将它定义为字符串,它也会出现,但与其他任何类型一样,它都不会出现。如果我将其声明为required并保留null,则会将其序列化为myInt="0"

我错过了什么?

一些细节:

XSD:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="graph">
    <xs:complexType>
      <xs:attribute name="myString" type="xs:string" />
      <xs:attribute name="myInt" type="xs:int" />
    </xs:complexType>
  </xs:element>
</xs:schema>

生成的类:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=false)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class graph {
    private string myStringField;
    private int myIntField;

    [System.Xml.Serialization.XmlAttributeAttribute(Form=System.Xml.Schema.XmlSchemaForm.Qualified)]
    public string myString {
        get { return this.myStringField; }
        set { this.myStringField = value; }
    }

    [System.Xml.Serialization.XmlAttributeAttribute(Form=System.Xml.Schema.XmlSchemaForm.Qualified)]
    public int myInt {
        get { return this.myIntField; }
        set { this.myIntField = value; }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool myIntSpecified {
        get { return this.myIntFieldSpecified; }
        set { this.myIntFieldSpecified = value; }
    }

3 个答案:

答案 0 :(得分:7)

XSD将为值类型的所有属性添加额外的“指定”字段。使用带有值类型的.NET序列化时,您始终需要指定字段的值并将匹配的“specified”属性设置为true。

将您的代码更改为此代码,它将按预期工作:

var myGraph = new graph();
myGraph.myString = "hallo";
myGraph.myInt = 80;
myGraph.myIntSpecified = true;

答案 1 :(得分:2)

我对此并不是100%肯定,但记住类似的东西。 查看生成的'myIntSpecified'字段?你应该把它设置为true。

xsd.exe有一些很大的限制,你可以google替代,或者只记得每次都设置为true。 :)

答案 2 :(得分:0)

还有一些东西在你身边我的朋友。我确实编译了代码并且完美地工作了:

类:

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class graph
{
    private string myStringField;
    private int myIntField;

    [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
    public string myString
    {
        get { return this.myStringField; }
        set { this.myStringField = value; }
    }

    [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
    public int myInt
    {
        get { return this.myIntField; }
        set { this.myIntField = value; }
    }


}

代码:

    graph g = new graph() {myInt = 80, myString = "ali"};
    XmlSerializer xss = new XmlSerializer(typeof (graph));
    MemoryStream ms = new MemoryStream();
    xss.Serialize(ms, g);
    StreamReader sb = new StreamReader(ms);
    ms.Position = 0;
    Console.WriteLine(sb.ReadToEnd());

输出:

<graph xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org
/2001/XMLSchema-instance" myString="ali" myInt="80" />