В настоящее время у меня проблема с созданием файлов классов из xsd с повторяющимися элементами. Я использую специальный инструмент «MsDatasetGenerator» в VS2005 SP1, который создает типизированный набор данных из xsd для C#. Я пытаюсь разобрать XML по этой схеме
<?xml version = "1.0" encoding=\"utf-8\"?>
<xs:schema id = "XSDobject" targetNamespace = "http://tempuri.org/XSDobject.xsd" elementFormDefault = "qualified" xmlns = "http://tempuri.org/XSDobject.xsd" xmlns:mstns = "http://tempuri.org/XSDobject.xsd" xmlns:xs = "http://www.w3.org/2001/XMLSchema">
<xs:element name = "order">
<xs:complexType>
<xs:sequence>
<xs:element name = "contact">
<xs:complexType>
<xs:sequence>
<xs:element name = "name" type = "xs:string" />
<xs:element name = "phone" type = "xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name = "buyer">
<xs:complexType>
<xs:sequence>
<xs:element name = "contact">
<xs:complexType>
<xs:sequence>
<xs:element name = "name" type = "xs:string" />
<xs:element name = "phone" type = "xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Но я получаю следующую ошибку «Одна и та же таблица contact не может быть дочерней таблицей в двух вложенных отношениях.»
XSD компилируется правильно, но это типизированный набор данных, который не может обрабатывать повторяющиеся таблицы. Теперь я протестировал также инструмент xsd.exe, но, похоже, он генерирует тот же код, что и msdatasetgenerator. Я также пробовал некоторые сторонние инструменты генератора кода, такие как XSD2Code, CodeXS, AltovaXmlSpy, но также не могу заставить его работать с вложенными элементами.
В качестве альтернативы я мог бы решить проблему с преобразованием xslt на входе и выходе, но это стоило бы мне большой производительности.
Итак, теперь я спрашиваю, может ли кто-нибудь помочь мне с хорошим решением для VS2005 или узнать хороший генератор классов xsd, который может справиться с этой проблемой. Это не обязательно должен быть типизированный набор данных, если он работает как массив или список, он также идеален, если его легко сериализовать и десериализовать.
заранее спасибо Freggel





Я бы предложил простое переименование элементов схемы, а также использование группировки (показано ниже) или включения xsd (если вам нужен этот сложный тип для других схем). Это должно решить проблему, если у вас нет жестких требований к именам.
По опыту я не думаю, что инструменты будут работать с повторяющимся именованием в вашем примере.
Что-то вроде этого может помочь:
<?xml version = "1.0" encoding = "utf-8"?>
<xs:schema id = "XSDobject" targetNamespace = "http://tempuri.org/XSDobject.xsd" elementFormDefault = "qualified" xmlns = "http://tempuri.org/XSDobject.xsd" xmlns:mstns = "http://tempuri.org/XSDobject.xsd" xmlns:xs = "http://www.w3.org/2001/XMLSchema">
<xs:group name = "Contact">
<xs:sequence>
<xs:element name = "name" type = "xs:string" />
<xs:element name = "phone" type = "xs:string" />
</xs:sequence>
</xs:group>
<xs:element name = "order">
<xs:complexType>
<xs:sequence>
<xs:element name = "OrderContact">
<xs:complexType>
<xs:sequence>
<xs:group ref = "Contact"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name = "buyer">
<xs:complexType>
<xs:sequence>
<xs:element name = "BuyerContact">
<xs:complexType>
<xs:sequence>
<xs:group ref = "Contact"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
У меня была такая же проблема ... если производительность не является проблемой, вы можете использовать XSLT для переименования "дочерних" таблиц с тем же именем (т.е. получившееся имя является объединением имени таблицы и ее родительского элемента):
...
<xsl:template match = "*">
<xsl:param name = "parentElm">
<xsl:value-of select = "name(..)" />
</xsl:param>
<xsl:choose>
<xsl:when test = "local-name() = 'Contact'">
<xsl:element name = "{concat('Contact',$parentElm)}">
<xsl:apply-templates select = "@* | node()" />
</xsl:element>
</xsl:when> <xsl:otherwise>
<xsl:element name = "{local-name()}">
<xsl:copy-of select = "@*" />
<xsl:apply-templates select = "@* | node()" />
</xsl:element>
</xsl:otherwise>
</xsl:choose> </xsl:template> ...
Возможно, вы можете использовать xsd: import / xsd: include, чтобы разделить xsd на несколько файлов, а затем использовать xsd.exe для компиляции каждого из них. Я думаю, вы можете указать пространство имен для генерации кода при работе с xsd.exe.
Я работал с генерацией классов из xsd: s пару лет назад, и почему-то решил использовать xsdobjgen.exe вместо xsd.exe.
Удачи!
Посмотрите на мое решение для этого пункта.
Одно и то же имя таблицы не может быть дочерней таблицей в двух вложенных отношениях.
Я предлагаю использовать «ref» в вашей схеме для ссылки на «повторяющиеся» элементы.