递归XSD帮助

时间:2010-04-11 15:10:49

标签: c# xml xsd xml-serialization xsd2code

我正在尝试学习一点XSD,我正在尝试为这个xml创建一个XSD:

<Document>
  <TextBox Name="Username" />
  <TextBox Name="Password" />
</Document>

...所以有一个元素,它是一个抽象的复杂类型。每个元素都有元素等等。 DocumentTextBox正在扩展Element

我骗了这个:

<?xml version="1.0" encoding="utf-8" ?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Document">
    <xs:complexType>
      <xs:complexContent>
        <xs:extension base="Element">

        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="Element" abstract="true">
    <xs:sequence minOccurs="0" maxOccurs="unbounded">
      <xs:element name="Element" type="Element"></xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="TextBox">
    <xs:complexContent>
      <xs:extension base="Element">
        <xs:attribute name="Name" type="xs:string" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:schema>

我使用Xsd2Code将其编译为C#,现在我尝试反序列化它:

var serializer = new XmlSerializer(typeof(Document));

var document = (Document)serializer.Deserialize(new FileStream("Document1.xml", FileMode.Open));

foreach (var element in document.Element1)
{
    Console.WriteLine(((TextBox)element).Name);
}

Console.ReadLine();

它不会打印任何东西。当我尝试像这样序列化时:

var serializer = new XmlSerializer(typeof(Document));

var document = new Document();

document.Element1 = new List<Element>();

document.Element1.Add(new TextBox()
{
    Name = "abc"
});

serializer.Serialize(new FileStream("d.xml", FileMode.Create), document);

...输出是:

<?xml version="1.0"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Element1>
    <Element xsi:type="TextBox">
      <Element1 />
      <Name>abc</Name>
    </Element>
  </Element1>
</Document>

什么时候应该是这样的:

<?xml version="1.0"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <TextBox Name="abc" />
</Document>

有关如何修复xsd或其他代码生成器的任何想法吗?

感谢。

1 个答案:

答案 0 :(得分:0)

在XSD代码中,查看声明名为“Element”的元素的行。如果要在XML文件中使用<xs:element name="TextBox" />,则应将此元素命名为<TextBox/>

实施上述更改后,您可以运行xsd.exe /c YourFile.xsd从XSD生成C#类。在C#项目中包含生成的文件,您将能够像这样使用它:

  Document d = new Document();
  d.TextBox = new TextBox[]
  {
    new TextBox() { Name = "Username" },
    new TextBox() { Name = "Password" },
  };
  XmlSerializer ser = new XmlSerializer(typeof(Document));            
  ser.Serialize(Console.Out, d);

您还可以将XML反序列化为C#对象。

<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <TextBox xsi:type="TextBox" Name="Username" />
  <TextBox xsi:type="TextBox" Name="Password" />
</Document>

请注意xsi:type属性 - 因为您声明TextBox元素属于Element类型,您必须提供在反序列化其中一个元素时要使用的具体类型实现。出于好奇,我尝试将名为TextBox的元素的XSD类型更改为TextBox类型,但是xsd.exe抛出了StackOverflowException。我笑了。它可能与Element和TextBox之间的递归类型关系有关,但也许不同的工具会以不同的方式处理它?<​​/ p>

相关问题