【问题标题】:Null values for nested items unmarshalling in JAXB/MOXY在 JAXB/MOXY 中解组的嵌套项的空值
【发布时间】:2015-02-25 19:59:50
【问题描述】:

JAXB 可以很好地解组 XML 文档中每种类型遇到的第一个元素,但将相同类型的任何嵌套元素的子元素保留为 null。

简单来说,有问题的结构如下:

sequence->media->audio->track->clipitem(->sequence etc etc)

所以,一个剪辑项也可能有一个嵌套序列,整个循环可以递归地重复。

遇到的第一个序列总是正确设置媒体。

但是,对于嵌套序列,媒体元素始终为空(即使它在 XML 中)

这些类是使用 XSD 中的 xjc 生成的。

为什么 unmarshall 不喜欢嵌套元素?除了嵌套元素之外,它都工作正常。注释嵌套元素有什么特别的吗?代码和注释非常简单。

任何线索将不胜感激。 谢谢, 约翰

JAXBContext jc = JAXBContext.newInstance(Xmeml.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Xmeml xmeml = (Xmeml) unmarshaller.unmarshal(inFile);


@XmlRootElement(name = "sequence")
public class Sequence {

    @XmlElement(required = true)
    protected String name;
    @XmlElement(required = true)
    protected BigInteger duration;
    @XmlElement(required = true)
    protected Rate rate;
    @XmlElement(required = true)
    protected Timecode timecode;
    @XmlElement(required = true)
    protected BigInteger in;
    @XmlElement(required = true)
    protected BigInteger out;
    @XmlElement(required = true)
    protected Media media;



@XmlRootElement(name = "clipitem")
public class Clipitem {

    @XmlElement(required = true)
    protected String name;
    @XmlElement(required = true)
    protected BigInteger duration;
    @XmlElement(required = true)
    protected Rate rate;
    protected boolean enabled;
    @XmlElement(required = true)
    protected BigInteger in;
    @XmlElement(required = true)
    protected BigInteger out;
    @XmlElement(required = true)
    protected BigInteger start;
    @XmlElement(required = true)
    protected BigInteger end;
    @XmlElement(required = true)
    protected String masterclipid;
    protected boolean ismasterclip;
    @XmlElement(required = true)
    protected Labels labels;
    @XmlElement(required = true)
    protected Comments comments;
    @XmlElement(required = true)
    protected Sequence sequence;

XML 很大,但这里有一个 sn-p,其中序列中的媒体不应该是 null。

    <track>
        <clipitem id="Nested Sequence">
            <name>Nested Sequence</name>
            <duration>815</duration>
            <rate>
                <ntsc>FALSE</ntsc>
                <timebase>25</timebase>
            </rate>
            <in>0</in>
            <out>815</out>
            <start>815</start>
            <end>1630</end>
            <sequence id="Nested Sequence1">
                <name>Nested Sequence</name>
                <duration>815</duration>
                <rate>
                    <ntsc>FALSE</ntsc>
                    <timebase>25</timebase>
                </rate>
                <timecode>
                    <rate>
                        <ntsc>FALSE</ntsc>
                        <timebase>25</timebase>
                    </rate>
                    <string>01:00:00:00</string>
                    <frame>90000</frame>
                    <source>source</source>
                    <displayformat>NDF</displayformat>
                </timecode>
                <in>-1</in>
                <out>-1</out>
                <media>
                    <video>
                        <format>
                            <samplecharacteristics>
                                <width>1920</width>
                                <height>1080</height>
                                <anamorphic>FALSE</anamorphic>
                                <pixelaspectratio>NTSC-601</pixelaspectratio>
                                <fielddominance>lower</fielddominance>
                                <rate>
                                    <ntsc>FALSE</ntsc>
                                    <timebase>25</timebase>
                                </rate>

【问题讨论】:

  • 看起来没问题,能不能把解析不正确的xml加进去。
  • 我添加了一个 XML 的 sn-p,其中序列内的媒体为空。整个 XML 非常庞大,所以最好不要全部发布。
  • 将所有 bean 和未正确解组的 xml 示例放置在某个位置(不完整,只有一个失败的分支就足够了)并添加指向它们的链接。因此,我们可以测试解组是否真的不起作用,或者它是否对您有利。原则上它应该工作。典型的罪魁祸首是命名空间问题,但您应该得到错误消息而不是空值。
  • 这是一个带有 bean 的 zip、一个 xml 和一个测试用例类 mrlimbic.com/test/testcase.zip
  • 如果重要的话,我在类路径上也有 eclipselink 2.5.2。

标签: java xml jaxb moxy


【解决方案1】:

您的 dom 对象与 xml 不匹配。例如,序列将 uuid 元素作为第一个元素,而您的 bean 将其作为最后一个元素,“updatebehavior”完全丢失。 其他豆类也存在类似问题。附加的 xml 文档根本无法针对您的 jaxb 模型进行验证,这可能是它无法正确读取的原因。

从您的模型中获取架构:

JAXBContext con = JAXBContext.newInstance(Xmeml.class);
File dir = new File("D:\\Temp\\schema");
con.generateSchema(new MySchemaOutputResolver(dir));

class MySchemaOutputResolver extends SchemaOutputResolver {

    protected File baseDir;

    public MySchemaOutputResolver(File dir)
    {
        super();
        baseDir =  dir;
    }

    @Override
    public Result createOutput( String namespaceUri, String suggestedFileName ) throws IOException {
        return new StreamResult(new File(baseDir,suggestedFileName));
    }
}

在解组时验证架构:

JAXBContext con = JAXBContext.newInstance(Xmeml.class);
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("D:\\Temp\\schema\\schema1.xsd"));
Unmarshaller umar = con.createUnmarshaller();
umar.setSchema(schema);
Xmeml mem = (Xmeml)umar.unmarshal(new File("D:\\Temp\\testcase\\Surround Test.xml"));

【讨论】:

  • 哇。下单很麻烦?如何让它不关心元素的顺序?排序将是一个问题,因为我需要解析的 XML 的顺序可能会有所不同并且来自不同的系统。我使用 XJC 从 XSD 生成这些。 XSD 来自翻译 DTD。然后我编辑了 XSD 以摆脱我不需要的部分并制作更漂亮的类。那我该怎么办?
  • 如果在 xsd 中这样定义,排序并不繁琐。如果它是模式中的序列,则顺序很重要(因此序列名称),如果它是袋子,则不重要。 bean 上的 @XmlType(name = "", propOrder = {...}) 强制执行该顺序。如果您删除它,订单将停止问题。您将用于生成类的 XSD 必须与您可能收到的所有文档格式相匹配,因此在删除元素时应将它们标记为 minOccurency=0,因此它们不是必需的。
  • 尽管如此,如果您的 xmls 可能变化如此之大,请从类中生成模式并始终在解组时使用它进行验证,这样至少您将在对象中获得异常而不是空值。这样您就可以知道发生了什么,并且可以根据需要更新您的 jaxb 模型。
  • 这是有道理的。所以我只是尝试删除所有 XmlType 注释,但仍然出现同样的问题。是否以某种方式使用类中的字段作为没有 XmlType 注释的排序?
  • 从类中生成模式并检查错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-31
  • 1970-01-01
  • 2021-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多