Проблема создания вложенных таблиц классов XSD - PullRequest
5 голосов
/ 29 декабря 2008

В настоящее время у меня проблема с генерацией файлов классов из 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

Ответы [ 4 ]

2 голосов
/ 29 декабря 2008

У меня была такая же проблема ... если производительность не является проблемой, вы можете использовать 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> ...
1 голос
/ 29 декабря 2008

Я бы предложил простое переименование элементов схемы, плюс использование группировки (показано ниже) или 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>
0 голосов
/ 08 апреля 2015

Посмотрите на мое решение для этого предмета.

Одна и та же таблица 'name' не может быть дочерней таблицей в двух вложенных отношениях

Я предлагаю использовать 'ref' в вашей схеме для ссылки на 'дубликаты' элементов.

0 голосов
/ 25 июня 2009

Возможно, вы можете использовать xsd: import / xsd: include, чтобы разбить xsd на несколько файлов, а затем использовать xsd.exe для компиляции каждого из них. Я думаю, что вы можете указать пространство имен для создания кода при работе с xsd.exe.

Я работал над созданием классов из xsd: s пару лет назад, и по какой-то причине я решил использовать xsdobjgen.exe вместо xsd.exe.

Удачи!

...