Как использовать JAXB для обработки сообщений из двух отдельных схем (с одинаковым именем корневого элемента) - PullRequest
3 голосов
/ 09 марта 2011

У нас есть клиент, который отправляет сообщения xml, созданные из двух отдельных схем.

Мы хотели бы обработать их в одном приложении, поскольку контент связан.

Мы не можем изменить схему клиента, которую он использует для создания сообщений XML ...

Мы можем изменить наши собственные копии двух схем (или binding.jxb) - если это поможет - чтобы включить в JAXB обработку сообщений, созданных из двух отдельных схем.

К сожалению, обе схемы имеют одинаковое имя корневого элемента (см. Ниже).

ВОПРОС: Запрещает ли JAXB абсолютную обработку двух схем с одинаковым именем корневого элемента?
- Если так, я остановлю свою охоту на «пасхальное яйцо» для решения этой проблемы ... --- Или есть какой-то обходной путь, который позволил бы нам использовать JAXB для обработки этих сообщений XML, созданных из двух разных схем?

schema1 (обратите внимание на имя корневого элемента: «A»):

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified">
    <xsd:element name="A">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="AA">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="AAA1" type="xsd:string" />
                            <xsd:element name="AAA2" type="xsd:string" />
                            <xsd:element name="AAA3" type="xsd:string" />
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
                <xsd:element name="BB">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="BBB1" type="xsd:string" />
                            <xsd:element name="BBB2" type="xsd:string" />
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

schema2 (обратите внимание, опять же, используя то же имя корневого элемента: «A»)

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified">
    <xsd:element name="A">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="CCC">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="DDD1" type="xsd:string" />
                            <xsd:element name="DDD2" type="xsd:string" />
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
                <xsd:element name="EEE">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="EEE1">
                                <xsd:complexType>
                                    <xsd:sequence>
                                        <xsd:element name="FFF1" type="xsd:string" />
                                        <xsd:element name="FFF2" type="xsd:string" />
                                    </xsd:sequence>
                                </xsd:complexType>
                            </xsd:element>
                            <xsd:element name="EEE2" type="xsd:string" />
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

Ответы [ 3 ]

1 голос
/ 10 марта 2011

Я попытался объединить две схемы (которые используют одно и то же имя элемента), как вы предложили ранее.

(примечание: мне пришлось использовать публикацию «Ответь на свой вопрос», чтобы включить примеры, поскольку комментарий допускает только ограниченное пространство)

Одна из проблем, с которыми я сталкиваюсь, заключается в том, что некоторые из подэлементов в реальной схеме (я не могу опубликовать фактическую схему) используют те же имена (я должен был воссоздать ниже, чтобы проиллюстрировать этот случай ... - заметьте, что «Группы» schema1 и schema2 содержат элементы с одинаковыми именами) ...

Вот схема.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:group name="schema1">
        <xs:sequence>
            <xs:element name="AA">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="CC1" type="xs:string"/>
                        <xs:element name="CC2" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="BB">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="DD1" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
          </xs:sequence>   
    </xs:group>
    <xs:group name="schema2">
        <xs:sequence>
            <xs:element name="AA">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="CC1" type="xs:string"/>
                        <xs:element name="CC2" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="BB">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="DD1">
                            <xs:complexType>
                                <xs:sequence>
                                    <xs:element name="EE1" type="xs:string"/>
                                    <xs:element name="EE2" type="xs:string"/>
                                </xs:sequence>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:group>
    <xs:element name="A">
        <xs:complexType>
            <xs:choice>
                <xs:group ref="schema1" />
                <xs:group ref="schema2" />
            </xs:choice>
        </xs:complexType>
    </xs:element>    
</xs:schema>

Я пытался запустить

xjc schemacombo.xsd -b binding.xjb

... где binding.xjb содержит

<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               jaxb:version="2.0">

    <jxb:bindings schemaLocation = "schemacombo.xsd" node="/xs:schema">>
      <jxb:schemaBindings>
        <jxb:bindings node="xs:group[@name='schema2']">
            <jxb:nameXmlTransform>
                <jxb:modelGroupName suffix="2"/>
            </jxb:nameXmlTransform>         
        </jxb:bindings>
        </jxb:schemaBindings>
    </jxb:bindings>

</jxb:bindings>

...- слабая попытка, я знаю, и она не работает ... то есть, выполнение этого приводит к:

parsing a schema...
[ERROR] cos-element-consistent: Error for type '#AnonType_A'. Multiple elements with name 'AA', with different types, appear in the model group.
  line 49 of file:/C:/AAAAA_delegate/schemacombo.xsd

[ERROR] cos-nonambig: AA and AA (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles.
  line 49 of file:/C:/AAAAA_delegate/schemacombo.xsd

Failed to parse a schema.

Есть ли у вас какие-либо предложения для заявлений о привязках или аннотаций, которые бы это исправили. - Обратите внимание, я до сих пор не видел работу с настроенными привязками, пока.

1 голос
/ 09 марта 2011

ВОПРОС: Запрещает ли JAXB абсолютную обработку двух схем с одинаковым именем корневого элемента?

ОТВЕТ: Вы можете сопоставить несколько классов с одним корневым элементом, но вам нужноуказать тип для немаршальной операции.

A1

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="A")
public class A1 {    
}

A2

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="A")
public class A2 {    
}

input.xml

<A/>

Демо

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(A1.class, A2.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xmlFile = new File("input.xml");
        StreamSource xmlSource = new StreamSource(xmlFile);
        A1 a1 = unmarshaller.unmarshal(xmlSource, A1.class).getValue();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.marshal(a1, System.out);
    }
}

Для получения дополнительной информации:

Ниже приведен пример файла привязок, который можно использовать для настройки класса, которому сопоставляется элемент.Я не вижу никакой связи между двумя схемами.Вы как-то объединяете их в одну операцию XJC?

<jxb:bindings 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">

    <jxb:bindings schemaLocation="schema1.xsd">
            <jxb:bindings node="//xs:element[@name='A']">
                <jxb:class name="RenamedA"/>
            </jxb:bindings>
    </jxb:bindings>
</jxb:bindings>
0 голосов
/ 10 марта 2011

к сожалению, проблема не в том, что корневые элементы имеют одинаковое имя, а в том, что они определены как один и тот же элемент - то есть одно и то же имя и одно и то же пространство имен. вы не сможете работать с этими схемами так, как вам хочется.

что вы можете сделать, хотя это означает, что для вас много работы по обслуживанию - объединить определения обеих схем в одно определение, используя выбор и групповые ссылки, например:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified">

<xsd:group name="schema1a">
        <xsd:sequence>
            <xsd:element name="AA">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="AAA1" type="xsd:string" />
                        <xsd:element name="AAA2" type="xsd:string" />
                        <xsd:element name="AAA3" type="xsd:string" />
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="BB">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="BBB1" type="xsd:string" />
                        <xsd:element name="BBB2" type="xsd:string" />
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
        </xsd:sequence>
    </xsd:group>

<xsd:group name="schema2a">
            <xsd:sequence>
                <xsd:element name="CCC">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="DDD1" type="xsd:string" />
                            <xsd:element name="DDD2" type="xsd:string" />
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
                <xsd:element name="EEE">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="EEE1">
                                <xsd:complexType>
                                    <xsd:sequence>
                                        <xsd:element name="FFF1" type="xsd:string" />
                                        <xsd:element name="FFF2" type="xsd:string" />
                                    </xsd:sequence>
                                </xsd:complexType>
                            </xsd:element>
                        <xsd:element name="EEE2" type="xsd:string" />
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
        </xsd:sequence>
    </xsd:group>
    <xsd:element name="A">
    <xsd:complexType>
        <xsd:choice>
            <xsd:group ref="schema1a" />
            <xsd:group ref="schema2a" />
        </xsd:choice>
    </xsd:complexType>
    </xsd:element>
</xsd:schema>

по существу, мы берем определения комплексного типа каждого элемента A схемы и меняем их на определение группы, затем мы включаем эти определения группы в элемент выбора. это эффективно позволило бы парсеру jaxb правильно обрабатывать документы, созданные с использованием любой схемы. между обновлениями обеих схем требуется много работы, но, возможно, это можно автоматизировать с помощью XSLT и некоторых сценариев.

надеюсь, это поможет

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