如何反序列化 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 中没有看到前缀 cenc
和 mspr
的任何命名空间声明。如果 undeclared/undefined,JAXB 不知道它们的 XML 类型定义。您还需要为它们提供模式以进行完整的模式验证。尽管完整模式验证对于 processContents="lax"
不是强制性的,但它有助于及早检测潜在的反序列化问题。此外,一般来说,验证输入总是更安全。
最后但同样重要的是,确保 JAXBContext(您从中创建 Unmarshaller)知道您要绑定的额外 JAXB-annotated classes cenc:pssh
和msgpr:pro
(实际上是他们的 XML 类型)。喜欢:
JAXBContext.newInstance(Pssh.class,Pro.class,...);
我正在使用 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 中没有看到前缀 cenc
和 mspr
的任何命名空间声明。如果 undeclared/undefined,JAXB 不知道它们的 XML 类型定义。您还需要为它们提供模式以进行完整的模式验证。尽管完整模式验证对于 processContents="lax"
不是强制性的,但它有助于及早检测潜在的反序列化问题。此外,一般来说,验证输入总是更安全。
最后但同样重要的是,确保 JAXBContext(您从中创建 Unmarshaller)知道您要绑定的额外 JAXB-annotated classes cenc:pssh
和msgpr:pro
(实际上是他们的 XML 类型)。喜欢:
JAXBContext.newInstance(Pssh.class,Pro.class,...);