如何反序列化 XML 列表?

How to deserialize an XML list?

我正在使用 jaxb2 反序列化 the MPEG Dash schema

Java classes 的生成效果很好,但是,Dash 清单中的部分信息丢失了。即,包含在 ContentProtection 元素内的数据。看起来像这样:

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

默认模式将内部字段放入带有 @XmlAnyElement 注释的 DescriptorType class 中,从而生成如下所示的对象列表:

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

为了尝试解决这个问题,我为 ContentProtection 创建了自己的 jxb 绑定,如下所示:

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

但是,我离获得其中包含的 Base64EncodedBlob 信息还很远。我不确定如何在自定义 class 中设置注释以正确构建列表。这是我试过的。

 //@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;
  }

我的 Pssh class 看起来像:

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;
  }
}

我该怎么做才能使 Pssh 对象列表使用 base64 blob 而不是 null 构建?

我建议您在 JAXB 解组器上启用 XML 模式验证。它通常会告诉您 XML 输入中阻止 JAXB 正确解组的所有错误内容(例如意外的 XML 内容,它不知道哪个 Java class(es ) 将其映射到)。它将使调试这类东西更容易。例如,我在您的 XML 中没有看到前缀 cencmspr 的任何命名空间声明。如果 undeclared/undefined,JAXB 不知道它们的 XML 类型定义。您还需要为它们提供模式以进行完整的模式验证。尽管完整模式验证对于 processContents="lax" 不是强制性的,但它有助于及早检测潜在的反序列化问题。此外,一般来说,验证输入总是更安全。

最后但同样重要的是,确保 JAXBContext(您从中创建 Unmarshaller)知道您要绑定的额外 JAXB-annotated classes cenc:psshmsgpr:pro(实际上是他们的 XML 类型)。喜欢:

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