Проверка XML по подэлементу в схеме - PullRequest
0 голосов
/ 28 апреля 2019

У меня есть одна схема XSD, которая принимает файлы XML, корневым элементом которых является <EnvioBOLETA>.Таким образом, правильный XML должен выглядеть так:

<EnvioBOLETA version="1.0" ns="..."> <!-- Attributes are irrelevant -->
   <SetDte>
      <Caratula>
         <RutEmisor>11111111-1</RutEmisor>
         <RutEnvia>66666666-6</RutEnvia>
         <RutReceptor>11111111-1</RutReceptor>
         <FchResol>2010-10-10</FchResol>
         <NroResol>0</NroResol>
         <SubTotDTE>
            <TpoDte>39</TpoDte>
            <NroDte>1</NroDte>
         </SubTotDTE>
      </Caratula>
      <DTE version="1.0"xmlns:siid="http://www.sii.cl/SiiDte">
         <Documento>
            <!--Elements with it's attributes-->
         </Documento>
         <Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <!--DTE's xmlsignature-->
         </Signature>
      </DTE>
   </SetDte>
   <Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
       <!--EnvioBOLETA's xmlsignature-->
   </Signature>
</EnvioBOLETA>

Если я использую JAXB, он создаст классы из всей схемы.Получающиеся классы выглядят так:

/* EnvioBOLETA */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "setDTE",
    "signature"
})
@XmlRootElement(name = "EnvioBOLETA")
public class EnvioBOLETA {

    @XmlElement(name = "SetDTE", required = true)
    protected EnvioBOLETA.SetDTE setDTE;
    @XmlElement(name = "Signature", namespace = "http://www.w3.org/2000/09/xmldsig#", required = true)
    protected SignatureType signature;
    @XmlAttribute(name = "version", required = true)
    protected BigDecimal version;

    /* Getters and Setters */

    /* SetDTE*/
    public static class SetDTE {

        @XmlElement(name = "Caratula", required = true)
        protected EnvioBOLETA.SetDTE.Caratula caratula;

        @XmlElement(name = "DTE", required = true)
        protected List<BOLETADefType> dte;

        @XmlAttribute(name = "ID", required = true)
        @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
        @XmlID
        @XmlSchemaType(name = "ID")
        protected String id;

        /* Getters and Setters and other static classes*/
    }
}

/* DTE */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "BOLETADefType", propOrder = {
    "documento",
    "signature"
})
public class BOLETADefType {

    @XmlElement(name = "Documento", required = true)
    protected BOLETADefType.Documento documento;
    @XmlElement(name = "Signature", namespace = "http://www.w3.org/2000/09/xmldsig#", required = true)
    protected SignatureType signature;
    @XmlAttribute(name = "version", required = true)
    protected BigDecimal version;

    /* Getters and Setters */
}

Я разрабатываю программу на Java, которая получает файл XML, содержащий только элемент <DTE> и все внутри него, поскольку остальные теги не требуются.Кроме того, элемент <DTE> не имеет своей подписи, потому что моя программа должна создать его, используя содержимое элемента <DTE>, а также содержимое файла PFX и файла PEM (оба эти значения не имеют значения).

Я выполнил следующие шаги для выполнения требования, описанного выше:

  1. Добавьте аннотацию @XmlRootElement(name = "DTE") к классу BOLETADefType.РЕЗУЛЬТАТ: при попытке отмены вызова входного XML с помощью следующего кода:
JAXBContext context = JAXBContext.newInstance(BOLETADefType.class);
Unmarshaller unMarshaller = context.createUnmarshaller();
InputStream xmlStream = new FileInputStream(args[0]);
Reader xmlReader = new InputStreamReader(xmlStream, "ISO-8859-1");
BOLETADefType dte = (BOLETADefType)unMarshaller.unmarshal(xmlReader);

Выдает следующее исключение:

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"DTE"). Expected elements are <{http://www.sii.cl/SiiDte}DTE>

То же, что и первый шаг, но установка пространства имен для пустой строки в аннотации @XMLRootElement над определением класса BOLETADefType, основанного на решении @dcbyers проблемы в javax.xml.bind.UnmarshalException: непредвиденный элемент (uri: . То есть:
/* DTE */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "DTE", namespace="")
@XmlType(name = "BOLETADefType", propOrder = {
    "documento",
    "signature"
})
public class BOLETADefType {
   //...
}

РЕЗУЛЬТАТ: Избегает javax.xml.bind.UnmarshalException, описанного выше, но объект dte имеет атрибуты documento и signature со значением null.

Аналогично шагу 1, но при создании Unmarshaller используется весь пакет вместо класса.Этот шаг основан на решении, заданном @lexicore для проблемы в Ошибка при неожиданном элементе (uri: "", local: "response").Ожидаемые элементы: <{} quote>
JAXBContext context = JAXBContext.newInstance(BOLETADefType.class.getPackage().getName());

РЕЗУЛЬТАТ: Это дает следующее исключение:

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"DTE"). Expected elements are <{http://www.sii.cl/SiiDte}DTE>,<{http://www.w3.org/2000/09/xmldsig#}Signature>
То же, что и на шаге 2, но установка пространства имен в аннотации @XmlType вместо аннотации @XmlRootElement:
/* DTE */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "DTE")
@XmlType(name = "BOLETADefType", namespace="", propOrder = {
    "documento",
    "signature"
})
public class BOLETADefType {
   //...
}

РЕЗУЛЬТАТ: То же, что и шаг 1.

Не используйте аннотацию @XmlRootElement, вместо этого определите объект BOLETADefType, как описано на другом сайте:
JAXBElement<BOLETADefType> jaxbElement = (JAXBElement<BOLETADefType>) unMarshaller.unmarshal(new StreamSource(xmlReader), BOLETADefType.class);
BOLETADefType dte = jaxbElement.getValue();

РЕЗУЛЬТАТ: То же, что и шаг 2.

ВОПРОСЫ:

  1. Есть ли способ отмены маршалинга входного XML-файла, чтобы у объекта Documento не было значений null с использованием JAXB?
  2. Если нет, есть ли способзагрузить XML в объекты без использования библиотеки JDOM, потому что использование этого стало бы моим худшим сценарием?

Заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...