Абстрактный класс Маршалла без определения его типа

Я пытаюсь добиться противоположного здесь. У меня есть абстрактный класс, но я не хочу, чтобы выводился тип и тег абстрактного класса. Итак, мне нужен вывод, который в основном выглядит как

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dokument ausgabe="ausgabe_test.doc" vorlage="vorlage_test.dot">
    <marke typ="text" name="test">
        <text>This is a test</text>
    </marke>
</dokument>

скорее, чем

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dokument ausgabe="ausgabe_test.doc" vorlage="vorlage_test.dot">
    <marke typ="text" name="test">
        <inhalt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="text">
            <text>This is a test</text>
        </inhalt>
    </marke>
</dokument>

Text наследуется от абстрактного класса Inhalt.

Моя текущая (сгенерированная) схема показана ниже.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="dokument" type="dokument"/>

  <xs:complexType name="dokument">
    <xs:sequence>
      <xs:element name="marke" type="marke" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="vorlage" type="xs:string" use="required"/>
    <xs:attribute name="ausgabe" type="xs:string" use="required"/>
  </xs:complexType>

  <xs:complexType name="marke">
    <xs:sequence>
      <xs:element name="inhalt" type="inhalt"/>
    </xs:sequence>
    <xs:attribute name="name" type="xs:string" use="required"/>
    <xs:attribute name="typ" type="markenTyp" use="required"/>
  </xs:complexType>

  <xs:complexType name="inhalt" abstract="true">
    <xs:sequence/>
    <xs:attribute name="style" type="xs:string"/>
  </xs:complexType>

  <xs:complexType name="text">
    <xs:complexContent>
      <xs:extension base="inhalt">
        <xs:sequence>
          <xs:element name="text" type="xs:string"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:simpleType name="markenTyp">
    <xs:restriction base="xs:string">
      <xs:enumeration value="text"/>
      <xs:enumeration value="tabelle"/>
      <xs:enumeration value="liste"/>
    </xs:restriction>
  </xs:simpleType>

</xs:schema>

person Jan    schedule 30.08.2010    source источник
comment
Вы не включили схему, поэтому немного сложно комментировать. В принципе, вы не можете сериализовать абстрактный элемент или тип, поскольку это незаконно...   -  person xcut    schedule 31.08.2010
comment
Моя схема сгенерирована, поэтому я подумал, что это будет не так интересно. Я добавил это к своему первоначальному вопросу.   -  person Jan    schedule 31.08.2010


Ответы (1)


Основываясь на предоставленной вами схеме, я бы сказал следующее: помните, что наследование сложных типов в XML-схеме не совсем такое же, как вы ожидаете в Java.

В вашей схеме/объектной модели у вас есть тип inhalt и тип text, который наследуется от него. inhalt является абстрактным. Все идет нормально. Разница заключается в использовании типов. Вы назначаете тип inhalt элементу с именем inhalt. Это означает, что там может появиться только элемент inhalt, а не text, и переопределение xsi:type необходимо, чтобы указать, какой подтип используется (парсер не может его угадать).

Вы можете достичь того, чего хотите, если используете группу замещения в дополнение к подтипу, это позволит появиться элементу text. Рефакторинг схемы следующим образом:

  1. Создайте глобальный элемент с именем «inhalt» и введите «inhalt» (сделайте имя типа в верхнем регистре, если вы думаете, что это сбивает с толку)
  2. Создайте глобальный элемент с именем «текст» и введите «текст». Установите для атрибута группы замещения «текст» значение «inhalt».
  3. Замените ссылку на локальный элемент в «marke» ссылкой на глобальный элемент.

Для справки вот новая модель marke:

<xs:element name="inhalt" type="inhalt"/>
<xs:element name="text" type="text" substitutionGroup="inhalt"/>
<xs:complexType name="marke">
    <xs:sequence>
        <xs:element ref="inhalt"/>
    </xs:sequence>
    <xs:attribute name="name" type="xs:string" use="required"/>
    <xs:attribute name="typ" type="markenTyp" use="required"/>
</xs:complexType>

После этого text может появиться внутри marke.

person xcut    schedule 02.09.2010
comment
Большое спасибо. Тем не менее, мне все еще нужно прочитать о группах замещения, чтобы понять их. - person Jan; 03.09.2010