递归 XSD 帮助

发布于 2024-08-28 14:56:12 字数 2527 浏览 3 评论 0原文

我正在尝试学习一点 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 或其他代码生成器?

谢谢。

i'm trying to learn a little bit XSD and I'm trying to create a XSD for this xml:

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

... so there's an element, which is an abstract complex type. Every element have elements and so on. Document and TextBox are extending Element.

I trid this:

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

I compiled it to C# with Xsd2Code, and now I try to deserialize it:

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();

and it dosen't print anything. When I try to serialize it like so:

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

...the output is:

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

When it should be something like:

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

Any ideas how to fix the xsd or another code generator?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小傻瓜 2024-09-04 14:56:12

在 XSD 代码中,查看声明名为“Element”的元素的行。如果您想在 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 之间的递归类型关系有关,但也许不同的工具会以不同的方式处理它?

In the XSD code, look at the line where you declare an element named "Element". This element should be named as such <xs:element name="TextBox" /> if you want to use <TextBox/> in your XML files.

With the above change implemented, you could run xsd.exe /c YourFile.xsd to generate a C# class from the XSD. Include the generated file in your C# project and you'll be able to use it like this:

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

You'll also be able to deserialize the XML back into C# objects.

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

Note the xsi:type attribute - because you declared your TextBox element to be of type Element you will have to provide which concrete type implementation to use when deserializing one of these elements. Out of curiosity I tried changing the XSD type of the element named TextBox to the TextBox type, but xsd.exe threw a StackOverflowException. I chuckled. It probably to do with the recursive type relationship between Element and TextBox, but maybe a different tool would handle it differently?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文