Рекурсивная справка по XSD - PullRequest
0 голосов
/ 11 апреля 2010

Я пытаюсь немного изучить XSD и пытаюсь создать XSD для этого xml:

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

Я скомпилировал его в C # с Xsd2Code, и теперь я пытаюсь десериализовать его:

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 голосов
/ 12 апреля 2010

В коде XSD посмотрите на строку, где вы объявляете элемент с именем «Элемент». Этот элемент должен быть назван как <xs:element name="TextBox" />, если вы хотите использовать <TextBox/> в ваших XML-файлах.

После внесения вышеуказанного изменения вы можете запустить xsd.exe /c YourFile.xsd, чтобы сгенерировать класс C # из XSD. Включите созданный файл в проект 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, вам нужно будет указать, какую конкретную реализацию типа использовать при десериализации одного из этих элементов. Из любопытства я попытался изменить тип XSD элемента с именем TextBox на тип TextBox, но xsd.exe вызвал исключение StackOverflowException. Я усмехнулся. Вероятно, это связано с рекурсивными типами отношений между Element и TextBox, но, возможно, другой инструмент справится с этим по-другому?

...