复杂类型内序列的 JAXB 外部绑定文件 xpath
JAXB external binding file xpath for sequence within complex type
我对 <jxb:bindings\>
中的 node
xpath 表达式有疑问:
我有一个在 xsd 中多次使用的类型,在它自己的 xsd:
中指定
common.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
targetNamespace="http://www.example.com/xsd/common"
xmlns="http://www.example.com/xsd/common"
xmlns:tns="http://www.example.com/xsd/common"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:complexType name="Parameter">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="key" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:schema>
多次包含在另一个模式中:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
targetNamespace="http://www.example.com/xsd/example"
xmlns="http://www.example.com/xsd/example"
xmlns:tns="http://www.example.com/xsd/example"
xmlns:c="http://www.example.com/xsd/common"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:element name="example" type="example" />
<xsd:complexType name="example">
<xsd:all>
<xsd:element name="working" type="working" />
<xsd:element name="notworking" type="notworking" />
</xsd:all>
</xsd:complexType>
<xsd:complexType name="working">
<xsd:all>
<xsd:element name="Parameters">
<xsd:sequence>
<xsd:element name="Parameter" type="c:Parameter" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:element>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="notworking">
<xsd:sequence>
<xsd:element name="Parameter" type="c:Parameter" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="anAttribute" type="xsd:token" />
</xsd:complexType>
</xsd:schema>
为了与 jaxb 绑定,我有一个 class ParameterMap:
package com.example.common.xml.model;
import java.util.HashMap;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.example.common.xml.binding.ParameterAdapter;
@XmlJavaTypeAdapter(ParameterAdapter.class)
public class ParameterMap extends HashMap<String, String> {}
以及适配器 class:
package com.example.common.xml.binding;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import com.example.common.xml.model.ObjectFactory;
import com.example.common.xml.model.Parameter;
import com.example.common.xml.model.ParameterMap;
public class ParameterAdapter extends XmlAdapter<List<Parameter>, ParameterMap> {
public ParameterMap unmarshal(List<Parameter> params) {
ParameterMap map = new ParameterMap();
for (Parameter p : params) {
map.put(p.getKey(), p.getValue());
}
return map;
}
public List<Parameter> marshal(ParameterMap map) {
List<Parameter> params = new ArrayList<>();
ObjectFactory of = new ObjectFactory();
for (Map.Entry<String, String> e : map.entrySet()) {
Parameter p = of.createParameter();
p.setKey(e.getKey());
p.setValue(e.getValue());
params.add(p);
}
return params;
}
}
当然还有绑定文件,使 classes 参数和 ObjectFactory 生成到正确的包中。示例命名空间的绑定文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc">
<jxb:bindings schemaLocation="../pathTo/example.xsd" node="/xs:schema">
<jxb:bindings node="//xs:complexType[@name='working']//xs:element[@name='Parameters']">
<jxb:class name="com.example.common.xml.model.ParameterMap" />
</jxb:bindings>
<jxb:bindings node="//xs:complexType[@name='notworking']//xs:element[@name='Parameter']">
<jxb:class name="com.example.common.xml.model.ParameterMap" />
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
正如您从命名中可以看出的那样,working
的子项的绑定生成正确,而 notworking
的绑定导致生成的 class 成员
@XmlElement(name = "Parameter")
protected List<ParameterMap> parameter;
我希望看起来像 working
:
@XmlElement(name="Parameters")
protected ParameterMap parameters;
"Parameter" 和 "Parameters" 并没有让我眼前一亮,但类型错误 - 任何有关如何实现该类型的帮助将不胜感激。
我也已经尝试将 notworking
绑定应用于序列(通过 node="//xs:complexType[@name='notworking']/xs:sequence"
),但它只是被忽略了。如果我尝试将它直接应用于 notworking
complexType,则会导致解析错误。
问题不在 XPath 中,它显然工作正常。
问题是这种方法行不通。 jaxb:class
不会将您的 collection 属性 转换为单个 属性,它只会配置 collection 项目的类型。
您可以为此编写一个 XJC 插件,但这有点复杂。
我对 <jxb:bindings\>
中的 node
xpath 表达式有疑问:
我有一个在 xsd 中多次使用的类型,在它自己的 xsd:
中指定common.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
targetNamespace="http://www.example.com/xsd/common"
xmlns="http://www.example.com/xsd/common"
xmlns:tns="http://www.example.com/xsd/common"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:complexType name="Parameter">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="key" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:schema>
多次包含在另一个模式中:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
targetNamespace="http://www.example.com/xsd/example"
xmlns="http://www.example.com/xsd/example"
xmlns:tns="http://www.example.com/xsd/example"
xmlns:c="http://www.example.com/xsd/common"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:element name="example" type="example" />
<xsd:complexType name="example">
<xsd:all>
<xsd:element name="working" type="working" />
<xsd:element name="notworking" type="notworking" />
</xsd:all>
</xsd:complexType>
<xsd:complexType name="working">
<xsd:all>
<xsd:element name="Parameters">
<xsd:sequence>
<xsd:element name="Parameter" type="c:Parameter" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:element>
</xsd:all>
</xsd:complexType>
<xsd:complexType name="notworking">
<xsd:sequence>
<xsd:element name="Parameter" type="c:Parameter" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="anAttribute" type="xsd:token" />
</xsd:complexType>
</xsd:schema>
为了与 jaxb 绑定,我有一个 class ParameterMap:
package com.example.common.xml.model;
import java.util.HashMap;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.example.common.xml.binding.ParameterAdapter;
@XmlJavaTypeAdapter(ParameterAdapter.class)
public class ParameterMap extends HashMap<String, String> {}
以及适配器 class:
package com.example.common.xml.binding;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import com.example.common.xml.model.ObjectFactory;
import com.example.common.xml.model.Parameter;
import com.example.common.xml.model.ParameterMap;
public class ParameterAdapter extends XmlAdapter<List<Parameter>, ParameterMap> {
public ParameterMap unmarshal(List<Parameter> params) {
ParameterMap map = new ParameterMap();
for (Parameter p : params) {
map.put(p.getKey(), p.getValue());
}
return map;
}
public List<Parameter> marshal(ParameterMap map) {
List<Parameter> params = new ArrayList<>();
ObjectFactory of = new ObjectFactory();
for (Map.Entry<String, String> e : map.entrySet()) {
Parameter p = of.createParameter();
p.setKey(e.getKey());
p.setValue(e.getValue());
params.add(p);
}
return params;
}
}
当然还有绑定文件,使 classes 参数和 ObjectFactory 生成到正确的包中。示例命名空间的绑定文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc">
<jxb:bindings schemaLocation="../pathTo/example.xsd" node="/xs:schema">
<jxb:bindings node="//xs:complexType[@name='working']//xs:element[@name='Parameters']">
<jxb:class name="com.example.common.xml.model.ParameterMap" />
</jxb:bindings>
<jxb:bindings node="//xs:complexType[@name='notworking']//xs:element[@name='Parameter']">
<jxb:class name="com.example.common.xml.model.ParameterMap" />
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
正如您从命名中可以看出的那样,working
的子项的绑定生成正确,而 notworking
的绑定导致生成的 class 成员
@XmlElement(name = "Parameter")
protected List<ParameterMap> parameter;
我希望看起来像 working
:
@XmlElement(name="Parameters")
protected ParameterMap parameters;
"Parameter" 和 "Parameters" 并没有让我眼前一亮,但类型错误 - 任何有关如何实现该类型的帮助将不胜感激。
我也已经尝试将 notworking
绑定应用于序列(通过 node="//xs:complexType[@name='notworking']/xs:sequence"
),但它只是被忽略了。如果我尝试将它直接应用于 notworking
complexType,则会导致解析错误。
问题不在 XPath 中,它显然工作正常。
问题是这种方法行不通。 jaxb:class
不会将您的 collection 属性 转换为单个 属性,它只会配置 collection 项目的类型。
您可以为此编写一个 XJC 插件,但这有点复杂。