JAXB XJC-компилятор, игнорирующий mixed = true в документах схемы XML - PullRequest
9 голосов
/ 29 октября 2010

XJC, похоже, полностью игнорирует mixed="true" в моих элементах XML-схемы, что не позволяет мне извлекать текстовое содержимое. Из приведенного ниже примера XML я должен быть в состоянии извлечь «Текст заголовка». Без распознавания mixed="true" средство доступа не создается и не демаршируется из XML:

<?xml version="1.0" encoding="UTF-8"?>
<title xmlns="urn:hl7-org:v3" integrityCheck="true">Title Text</title>

Вот полная, но минимизированная схема, демонстрирующая проблему:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema targetNamespace="urn:hl7-org:v3"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns="urn:hl7-org:v3"
  xmlns:mif="urn:hl7-org:v3/mif"
  elementFormDefault="qualified">

  <xs:complexType name="ST" mixed="true">
  <xs:complexContent>
         <xs:restriction base="ED">
            <xs:sequence>
               <xs:element name="reference" type="xs:string" minOccurs="0" maxOccurs="0"/>
               <xs:element name="thumbnail" type="xs:string" minOccurs="0" maxOccurs="0"/>
            </xs:sequence>
            <xs:attribute name="compression" type="xs:string" use="prohibited"/>
         </xs:restriction>
      </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="ED" mixed="true">
    <xs:complexContent>
      <xs:extension base="BIN">
        <xs:sequence>
          <xs:element name="reference" type="xs:string" minOccurs="0" maxOccurs="1" />
          <xs:element name="thumbnail" minOccurs="0" maxOccurs="1" type="xs:string" />
            </xs:sequence>
        <xs:attribute name="compression" type="xs:string" use="optional" />
        <xs:attribute name="integrityCheck" type="xs:string" use="optional" />
        <xs:attribute name="integrityCheckAlgorithm" type="xs:string" use="optional" default="SHA-1" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="BIN" abstract="true" mixed="true">
    <xs:complexContent>
      <xs:extension base="ANY">
        <xs:attribute name="representation" use="optional" type="xs:string" default="TXT" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="ANY" abstract="true">
    <xs:attribute name="nullFlavor" type="xs:string" use="optional" />
  </xs:complexType>

  <xs:element name="title" type="ST" />
</xs:schema>

Обратите внимание, что в приведенном выше примере я смешал = "true". Несмотря на это, сгенерированный фрагмент схемы не содержит ссылки на него, а также сгенерированный класс не использует аннотацию XmlMixed, а также средство доступа к значению или содержимому:

<code>/**
 * <p>Java class for ST complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.                                                                                                                                              
 * 
 * <pre>
 * <complexType name="ST">
 *   <complexContent>
 *     <restriction base="{urn:hl7-org:v3}ED">
 *       <sequence>
 *         <element name="reference" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="0" minOccurs="0"/>
 *         <element name="thumbnail" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="0" minOccurs="0"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * / @XmlAccessorType (XmlAccessType.FIELD) @XmlType (name = "ST") общественный класс ST расширяет ЭД { }

Почему XJC / JAXB полностью игнорирует мои поля смешанного контента? Я пробовал JAXB 2.1 и JAXB 2.2, но в сгенерированном коде присутствуют только тривиальные различия.

Примечание : Я не могу изменить схему, поскольку действительная схема является схемой здравоохранения, соответствующей стандартам (HL7).

Ответы [ 3 ]

5 голосов
/ 15 июня 2011

После дополнительных исследований я ничего не мог сделать, кроме как заключить, что это была ошибка, которую я подал. Это было признано как JAXB выпуск # 792 .

5 голосов
/ 15 июня 2011

http://blogs.oracle.com/mgrebac/entry/handling_extended_mixed_content_in

Это сработало! Просто создайте файл привязки примерно так:

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings
 xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"
 xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc">
  <jaxb:globalBindings generateMixedExtensions="true"/>
</jaxb:bindings>

Затем используйте параметр -b в командной строке так, как вы обычно это делаете.

3 голосов
/ 25 октября 2017

Проходят годы, но эта схема продолжает беспокоить людей! Последние несколько дней я боролся с тем же XSD (HL7), особенно за обработку смешанных типов элементов контента.

Мое первоначальное требование было противоположно исходному постеру, так как мне нужно было написать простой текст внутри смешанного элемента. Но я также должен иметь возможность читать такой контент, поэтому я применил то же решение, которое было предложено в другом ответе, а именно: создание собственного файла привязки и его использование в мастере Eclipse «JAXB Classes from Schema». В этом случае вы можете указать, какие файлы привязки использовать в одном из диалоговых окон мастера.

В результате классы создаются с содержимым List<Serializable> всякий раз, когда обнаруживается смешанный тип элемента. Получить некоторую информацию, которая вам действительно нужна, немного сложнее, но, по крайней мере, вы уверены, что можете программно получить доступ ко всему, что присутствует в файле XML, придерживающемся этого XSD.

Вы даже можете перейти к более сложному смешанному содержимому, например:

<v3:name>
    <v3:given>Sample Given Name</v3:given>
    <v3:family>Sample Family Name</v3:family>
</v3:name>

Где name определено как таковое (я удалил содержимое, не пригодное для этого примера, из исходного XSD):

<xs:complexType name="EN" mixed="true">
    <xs:complexContent>
        <xs:sequence>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element name="delimiter" type="en.delimiter"/>
                <xs:element name="family" type="en.family"/>
                <xs:element name="given" type="en.given"/>
                <xs:element name="prefix" type="en.prefix"/>
                <xs:element name="suffix" type="en.suffix"/>
            </xs:choice>
        </xs:sequence>
    </xs:complexContent>
</xs:complexType>

Типы en.family, en.given и тому подобное смешиваются друг с другом (и для нашей цели нам больше ничего не нужно знать).

Таким образом, при доступе к содержимому имени его List<Serializable> будет состоять из:

  1. a String, будучи пробелами между <v3:name> и <v3:given>
  2. элемент EnGiven
  3. a String, будучи пробелами между </v3:given> и <v3:family>
  4. и EnFamily элемент
  5. a String, будучи пробелами между </v3:family> и </v3:name>
Каждое содержимое

EnGiven и EnFamily будет состоять из одного String, соответственно «Имя образца» и «Имя семейства образца». Опять же, это немного сложно, и вам, вероятно, придется применить некоторую логику для обработки конкретных случаев, но вы можете справиться с этим следующим образом.

Кстати, заполнение элемента тривиально: просто добавьте строку к желаемому List<Serializable> содержимому.

...