Как я могу поддерживать с чередованием неизвестно XML с использованием JAXB?Использование @ XmlAnyElement не похоже на работу ..
Я пытаюсь написать схему XML, чтобы разрешить чередующиеся элементы из других пространств имен, и использовать это со встроеннымJAXB в Java 6. (Я не пробовал это полностью с JAXB 2.2.1, так как у меня нет роскоши требовать от моих пользователей API делать магию с поддержкой библиотек JAXB, но я верю в этотоже не работает с 2.2.1)
Так, например, учитывая схему everything.xsd , этот example.xml должен быть действительным:
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://example.com/schema"
xmlns:other="http://example.com/other">
<rootFiles>
<other:before>before rootFile</other:before>
<rootFile path="test" />
<other:after>after rootFile</other:after>
</rootFiles>
</container>
Любой XML из других пространств имен должен быть разрешен как до, так и после <rootFile>
.
Схематически это довольно просто, используя элементы <xsd:any>
до и после <xsd:element>
за <rootFile>
. Чередование вокруг необязательных элементов сложнее, но это отдельный пост.Уловка заключается в том, чтобы вместо этого сделать необязательной группу оберток: <xsd:sequence minOccurs="0"><xsd:element minOccurs="1" .. /><xsd:any /></xsd:sequence>
Я добавил jaxb: свойство , чтобы указать различные имена свойств для свойств any до / после.Я должен был сделать это, чтобы XJC не жаловался на Свойство «Any» уже определено .
Проблема в том, что JAXB, кажется, забрасывает все неизвестные элементы в anyBefore свойство, как видно при повторной сортировке неупорядоченного элемента (см. полный пример Maven Project ):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<container xmlns="http://example.com/schema">
<rootFiles>
<other:before xmlns:other="http://example.com/other">before rootFile</other:before>
<other:after xmlns:other="http://example.com/other">after rootFile</other:after>
<rootFile path="test"/>
</rootFiles>
</container>
Это делает невозможным проверку rootFiles.getAnyAfter()
, чтобы увидеть, какие неизвестные пришлигде, но более серьезно для меня, невозможно снова сериализовать XML без возражений по поводу чередующегося XML.
XJC правильно создает два любых -объекта:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"anyBefore",
"rootFile",
"anyAfter"
})
public static class RootFiles {
@XmlAnyElement(lax = true)
protected List<Object> anyBefore;
@XmlElement(required = true)
protected List<Container.RootFiles.RootFile> rootFile;
@XmlAnyElement(lax = true)
protected List<Object> anyAfter;
JavaDoc для XmlAnyElement говорит:
Эта аннотация является взаимоисключающей с XmlElement, XmlAttribute, XmlValue, XmlElements, XmlID и XmlIDREF.В классе и его суперклассах может быть только одно аннотированное свойство XmlAnyElement JavaBean.
Исходя из этого, я пришел к выводу, что JAXB на самом деле не заботится о втором @XmlAnyElement
, а просто размещает всепрямые неизвестные в первое любое свойство.Я застрял в том, что делать.
Обратите внимание, что моя главная задача - сохранить неизвестные элементы в нужном месте (порядок, кажется, сохранен), меня не особо волнует их анализ,просто убедитесь, что они находятся в одном и том же месте при повторной сериализации XML после некоторых модификаций элементов .
Теперь вы можете задаться вопросом, почему я разработал бы такую глупую схему, допускающую случайноеXML повсюду.К сожалению, это не моя вина, я просто пытаюсь вручную преобразовать эту схему RELAX NG из спецификаций Adobe UCF в схему XML , которую я могу использовать сJAXB.Проблема заключается в этой формулировке , которая разрешает любые внешние XML-элементы и атрибуты в META-INF / container.xml:
Соответствующие пользовательские агенты UCF ДОЛЖНЫ игнорировать нераспознанные элементы (и их содержимое).и нераспознанные атрибуты в файле container.xml, включая нераспознанные элементы и нераспознанные атрибуты из других пространств имен.
Соответствующие файлы container.xml ДОЛЖНЫ быть действительными в соответствии со схемой RELAX NG UCF с элементом в качестве корневого элемента после удалениявсе элементы (и дочерние узлы этих элементов) и атрибуты из других пространств имен.
Теперь я, конечно, мог бы просто удалить любые такие элементы, так как он говорит, что я могу их игнорировать, но я подумал, что если вБудущее или какое-то расширение они что-то значат, по крайней мере, я мог бы правильно сохранить такие элементы. Однако я нахожу это трудным, используя JAXB.
Есть ли какие-либо предложения о том, как мне этого добиться, например, некоторые магические свойства маршаллера/ Unmarshaller