0

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

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

...所以有一个元素,它是一个抽象的复杂类型。每个元素都有元素等等。Document并且TextBox正在扩展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 或其他代码生成器?

谢谢。

4

1 回答 1

0

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

实施上述更改后,您可以运行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 之间的递归类型关系有关,但也许不同的工具会以不同的方式处理它?

于 2010-04-11T22:59:35.633 回答