我必须从我无法控制的外部系统解组和处理XML。 XML是我认为的俄罗斯娃娃格式,它不易于处理。
XML共享在公共XSD文件中声明的常见类型。但是当JABX为这些类型生成JAVA类时,每个外部类都包含常见类型的嵌套声明,这使得它们在JAVA方面具有不同的类型。
我希望有通用的JAVA函数来处理XML中的常见嵌套类型,但是这不像JAXB类那样有效,这些常见类型是无关的。
这使我需要处理这些常见类型的JAVA代码非常混乱,我一直在尝试使用JAXB绑定来解决问题。但我没有成功。所以我的问题是: 鉴于这种格式的XML / XSD可以通过绑定或其他方法生成常见类型的JAVA代码吗?
这是一个例子;
XML CLASSA&有两个类。 CLASSB。两者都包含一个复杂类型,其中一个值类型为testTYPE,它是一个字符串。 XSD是:
CLASSA.XSD
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:nstype="http://www.test.com/nstypes"
elementFormDefault="qualified">
<xs:import namespace="http://www.test.com/nstypes" schemaLocation="nstypes.xsd"/>
<xs:element name="CLASSA">
<xs:complexType>
<xs:sequence>
<xs:element name="Prop" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="PROP" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="Value" type="nstype:testTYPE" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
B类有一个意识结构,只是一个不同的名称。
CLASSB.XSD
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:nstype="http://www.test.com/nstypes"
elementFormDefault="qualified">
<xs:import namespace="http://www.test.com/nstypes" schemaLocation="nstypes.xsd"/>
<xs:element name="CLASSB">
<xs:complexType>
<xs:sequence>
<xs:element name="Prop" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="PROP" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="Value" type="nstype:testTYPE" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
nstype类型中唯一称为Value的元素:testTYPE在nstypes.xsd中声明。它实际上是一个BASETYPE,它是一个String。
nstypes.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:nstypes="http://www.test.com/nstypes"
targetNamespace="http://www.test.com/nstypes"
elementFormDefault="unqualified">
<xs:complexType name="BASETYPE">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="TYPE" fixed="BASETYPE"/>
<xs:attribute name="derived" use="optional"/>
<xs:attribute name="readonly" use="optional"/>
<xs:attribute name="required" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="testTYPE">
<xs:simpleContent>
<xs:extension base="nstypes:BASETYPE"/>
</xs:simpleContent>
</xs:complexType>
</xs:schema>
CLASSA和CLASSB的XML类似
ClassA.xml
<?xml version="1.0" encoding="UTF-8"?>
<CLASSA>
<Prop>
<PROP>
<Value>AAA</Value>
</PROP>
</Prop>
</CLASSA>
ClassB.xml
<?xml version="1.0" encoding="UTF-8"?>
<CLASSB>
<Prop>
<PROP>
<Value>BBB</Value>
</PROP>
</Prop>
</CLASSB>
一旦生成了JAXB类,我就想写一些这样的代码:
testJAXB
import java.io.InputStream;
import org.generated.CLASSA.CLASSA;
import org.generated.CLASSA.TestTYPE;
import org.generated.CLASSB.CLASSB;
public class testJAXB
{
// there is a util function public static Object loadXML(String xmlFile, String fileName) throws Exception;
public static void main(String[] args) throws Exception
{
// create a ClassA & a ClassB
CLASSA anAClass = (CLASSA) loadXML("C:\\input\\ClassA.xml", "CLASSA");
CLASSB anBClass = (CLASSB) loadXML("C:\\input\\ClassB.xml", "CLASSB");
static void printClass(TestTYPE v)
{
// as CLASSA.TestTYPE is imported so v is a CLASSA.TestTYPE
System.out.println(v.toString());
}
// this call will work as there is a printClass which takes a CLASSA.TestTYPE
printClass(anAClass.getProp().getPROP().getValue());
// this call will not compile becase there is no printClass which takes a CLASSA.TestTYPE
printClass(anBClass.getProp().getPROP().getValue());
System.out.println("complete.");
}
}
我真正想做的是有一个函数printClass()的实现。我想这必须采用org.generated.TestTYPE,并且所有JAXB类都将使用org.generated.TestTYPEs ratehr而不是org.generated.CLASSA.TestTYPEs生成。 我希望通过一些绑定魔法可以实现。如果有人能指出我正确的方向,那将非常感激。
我有C ++而不是JAVA背景,所以如果我的某些术语不正确,请道歉。
杰罗姆,
这是我想看到的,但是我在CLASSA中看到的xjc
public CLASSA.Prop getProp()
其中CLASSA.Prop是包含
的静态类protected CLASSA.Prop.PROP
这是另一个包含
的静态类 protected TestTYPE value;
和TestTYPE是
org.generated.CLASSA.TestTYPE
CLASSB中的TestTYPE是
org.generated.CLASSB.TestTYPE
因为两个TestTYPE嵌套在不同的类中,所以它们是不同的类型。
基本上,当运行xjc时,我得到两个包含TestTYPE类的文件:
CLASSA / TestTYPE.JAVA
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.09.07 at 07:45:23 AM BST
//
package org.generated.CLASSA;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for testTYPE complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="testTYPE">
* <simpleContent>
* <extension base="<http://www.test.com/nstypes>BASETYPE">
* </extension>
* </simpleContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "testTYPE")
public class TestTYPE
extends BASETYPE
{
}
and
CLASSB / TestTYPE.JAVA
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.09.07 at 07:45:23 AM BST
//
package org.generated.CLASSB;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for testTYPE complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="testTYPE">
* <simpleContent>
* <extension base="<http://www.test.com/nstypes>BASETYPE">
* </extension>
* </simpleContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "testTYPE")
public class TestTYPE
extends BASETYPE
{
}
答案 0 :(得分:1)
我认为JAXB不会将这样的代码分解。 IMO更简单的解决方案是编写类Prop的代码,并在绑定文件中定义B.Prop和A.Prop都依赖于同一个类。
例如使用classImpl属性。 http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/2.0/tutorial/doc/JAXBUsing4.html#wp148576
答案 1 :(得分:0)
鉴于这种格式的XML / XSD可以使用常见类型的JAVA代码 通过绑定或其他方法生成?
使用JDK的xjc tool。
将所有文件放在目录中,然后执行:
xjc *.xsd
你会看到它生成文件:
parsing a schema...
compiling a schema...
generated\CLASSA.java
generated\CLASSB.java
generated\ObjectFactory.java
com\test\nstypes\BASETYPE.java
com\test\nstypes\ObjectFactory.java
com\test\nstypes\TestTYPE.java
com\test\nstypes\package-info.java
你会在CLASSA.java中看到你有一个方法调用getProp(),它返回一个CLASSA.Prop,你可以在其上做另一个getProp():
在CLASSA中你有:
public CLASSA.Prop getProp()
在CLASSA.Prop中你有:
public CLASSA.Prop.PROP getPROP()
在CLASSA.Prop.PROP
中,值为com.test.nstypes.TestTYPE
类型,这是您不依赖于CLASSA或CLASSB的常见类型。