How to deserialize an XML list?

时间:2018-01-23 19:37:18

标签: java jaxb jaxb2 mpeg-dash maven-jaxb2-plugin

I'm deserizaling the MPEG Dash schema using jaxb2.

The generation of the Java classes works great, however, part of the information in the Dash manifest is lost. Namely, data contained inside the ContentProtection element. Which looks something like this:

  <ContentProtection schemeIdUri="urn:uuid:SomeIdHash" value="PlayReady">                                                                                
    <cenc:pssh>Base64EncodedBlob</cenc:pssh>          
    <mspr:pro>Base64EncodedBlob</mspr:pro>                                                        
  </ContentProtection> 

The default schema throws the inner fields into a DescriptorType class with @XmlAnyElement annotation that results in a List of objects that looks like this:

[[cenc:pssh: null], [mspr:pro: null]] 

To attempt to fix the issue, I created my own jxb binding for the ContentProtection like so:

<jxb:bindings node="//xs:complexType[@name='RepresentationBaseType']/xs:sequence/xs:element[@name='ContentProtection']">
    <jxb:class ref="com.jmeter.protocol.dash.sampler.ContentProtection"/>
</jxb:bindings>

However, I'm not closer to getting the Base64EncodedBlob information contained within. I'm not sure how to setup my annotations in the custom class to construct the list correctly. This is what I've tried.

 //@XmlAnyElement(lax = true) //[[cenc:pssh: null], [mspr:pro: null]] 
  // @XmlJavaTypeAdapter(Pssh.class) //DOESNT WORK
  // @XmlValue //Empty List???
  // @XmlSchemaType(name = "pssh")
  // @XmlElementRef(name = "pssh") //Not matching annotations
  // @XmlElement(name = "enc:pssh") //Not matching annotations
  protected List<Pssh> pssh;

public List<Pssh> getPssh() {
    if (pssh == null) {
      pssh = new ArrayList<Pssh>();
    }
    return this.pssh;
  }

My Pssh class looks like:

package com.jmeter.protocol.dash.sampler;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlType(name = "enc:pssh")
// @XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "cenc:pssh")

public class Pssh {

  // @XmlValue
  //@XmlElement
  private String psshValue;

  public String getPsshValue() {
    return psshValue;
  }

  public void setPsshValue(String psshValue) {
    this.psshValue = psshValue;
  }
}

What can I do to make the List of Pssh objects get constructed with the base64 blobs instead of null?

1 个答案:

答案 0 :(得分:0)

我建议您在JAXB unmarshaller上启用XML模式验证。它通常会告诉您XML输入中的所有错误信息都会阻止JAXB正确地解组(就像意外的XML内容一样,它不知道将哪个Java类映射到它)。它将使调试这种东西更容易。例如,我在XML中看不到前缀cencmspr的任何名称空间声明。如果未声明/未定义,JAXB不知道它们的XML类型定义。您需要为它们提供模式以及完整模式验证。虽然processContents="lax"不强制进行完整模式验证,但它有助于及早发现潜在的反序列化问题。此外,一般来说,验证输入总是更安全。

最后但并非最不重要的是,确保您从中创建Unmarshaller的JAXBContext知道要绑定的额外JAXB注释类cenc:psshmsgpr:pro(它们的XML类型)实际上)。像:

JAXBContext.newInstance(Pssh.class,Pro.class,...);