问题:
我有两个班级:
问题是默认的Oracle(Sun)XmlSchemaGenerator生成了一个有效的XML Schema,但Eclipselink / MOXy SchemaGenerator似乎没有这样做。
Eclipse报告无效的XSD:
s4s-elt-invalid-content.1: The content of 'myAnyAttr' is invalid. Element 'anyAttribute' is invalid, misplaced, or occurs too often.
xmllint报道:
Element '{http://www.w3.org/2001/XMLSchema}complexType': The content is not valid. Expected is (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))).
我认为已经解决了这个问题。我提供了所有(大部分)必需的资源。
由MOXy生成的XSD(xsd:anyAttribute是违规元素):
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="myAnyAttr">
<xsd:complexContent>
<xsd:extension base="abstractKeyedItem">
<xsd:sequence>
<xsd:element name="kid" type="myAnyAttr" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
<xsd:anyAttribute processContents="skip" namespace="##other"/>
</xsd:complexType>
<xsd:complexType name="abstractKeyedItem" abstract="true">
<xsd:sequence/>
<xsd:attribute name="key" type="xsd:string"/>
</xsd:complexType>
<xsd:element name="my-any-attr-root" type="myAnyAttr"/>
</xsd:schema>
Oracle生成的XSD:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="my-any-attr-root" type="myAnyAttr"/>
<xs:complexType name="myAnyAttr">
<xs:complexContent>
<xs:extension base="abstractKeyedItem">
<xs:sequence>
<xs:element name="kid" type="myAnyAttr" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="skip"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="abstractKeyedItem" abstract="true">
<xs:sequence/>
<xs:attribute name="key" type="xs:string"/>
</xs:complexType>
</xs:schema>
抽象类:
package xml.anyattr;
import javax.xml.bind.annotation.XmlAttribute;
public abstract class AbstractKeyedItem {
@XmlAttribute
public String key;
public AbstractKeyedItem() {}
}
具体类:
package xml.anyattr;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.namespace.QName;
@XmlRootElement(name = "my-any-attr-root")
@XmlAccessorType(XmlAccessType.FIELD)
public class MyAnyAttr extends AbstractKeyedItem {
@XmlAnyAttribute
public Map<QName, String> attrMap = new HashMap<QName, String>();
@XmlElement(name = "kid")
public List<MyAnyAttr> myAnyAttrKids = new ArrayList<MyAnyAttr>();
public MyAnyAttr() {}
}
用于生成文件的实用程序:
package xml.anyattr;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.bind.SchemaOutputResolver;
import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import org.apache.pdfbox.io.IOUtils;
public class MyAnyAttrUtils {
private static class MySchemaOutputResolver extends SchemaOutputResolver {
@Override
public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
new Throwable().printStackTrace(System.out);
File file = null;
if (namespaceUri.equals("")) {
file = XSD;
} else {
throw new IOException("Unsupported namespaceUri: " + namespaceUri);
}
StreamResult result = new StreamResult(file);
result.setSystemId(file.toURI().toURL().toString());
return result;
}
}
static File XSD = new File("target/test-classes/my-any-utils.xsd");
private static void generateXsd() throws JAXBException, IOException {
rm(XSD);
JAXBContext jaxbContext = JAXBContext.newInstance(MyAnyAttr.class);
SchemaOutputResolver outputResolver = new MySchemaOutputResolver();
jaxbContext.generateSchema(outputResolver);
InputStream is = new FileInputStream(XSD);
System.out.println("XSD:");
IOUtils.copy(is, System.out);
}
public static void main(String[] args) {
try {
printSimple();
generateXsd();
System.exit(0);
} catch (Exception e) {
e.printStackTrace(System.err);
System.exit(1);
}
}
private static void printSimple() throws JAXBException, PropertyException {
MyAnyAttr myAnyAttr = new MyAnyAttr();
myAnyAttr.key = "parent";
myAnyAttr.attrMap.put(new QName("oth", "dad"), "foo");
MyAnyAttr kid = new MyAnyAttr();
kid.key = "child";
kid.attrMap.put(new QName("oth", "kid"), "bar");
myAnyAttr.myAnyAttrKids.add(kid);
JAXBContext jaxbContext = JAXBContext.newInstance(MyAnyAttr.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
System.out.println("XML:");
marshaller.marshal(myAnyAttr, System.out);
System.out.println();
}
private static void rm(File file) throws IOException {
if (file.exists()) {
if (!file.delete()) {
throw new IOException("Failed to delete " + file);
}
}
}
}
Oracle实施的堆栈跟踪:
java.lang.Throwable
at xml.anyattr.MyAnyAttrUtils$MySchemaOutputResolver.createOutput(MyAnyAttrUtils.java:25)
at com.sun.xml.internal.bind.v2.schemagen.FoolProofResolver.createOutput(FoolProofResolver.java:55)
at com.sun.xml.internal.bind.v2.schemagen.XmlSchemaGenerator.write(XmlSchemaGenerator.java:462)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.generateSchema(JAXBContextImpl.java:794)
at xml.anyattr.MyAnyAttrUtils.generateXsd(MyAnyAttrUtils.java:44)
at xml.anyattr.MyAnyAttrUtils.main(MyAnyAttrUtils.java:53)
MOXy实现的堆栈跟踪:
java.lang.Throwable
at xml.anyattr.MyAnyAttrUtils$MySchemaOutputResolver.createOutput(MyAnyAttrUtils.java:25)
at org.eclipse.persistence.jaxb.compiler.SchemaGenerator.getSchemaForNamespace(SchemaGenerator.java:687)
at org.eclipse.persistence.jaxb.compiler.SchemaGenerator.addSchemaComponents(SchemaGenerator.java:177)
at org.eclipse.persistence.jaxb.compiler.SchemaGenerator.generateSchema(SchemaGenerator.java:154)
at org.eclipse.persistence.jaxb.compiler.SchemaGenerator.generateSchema(SchemaGenerator.java:142)
at org.eclipse.persistence.jaxb.compiler.Generator.generateSchemaFiles(Generator.java:221)
at org.eclipse.persistence.jaxb.JAXBContext.generateSchema(JAXBContext.java:405)
at org.eclipse.persistence.jaxb.JAXBContext.generateSchema(JAXBContext.java:353)
at xml.anyattr.MyAnyAttrUtils.generateXsd(MyAnyAttrUtils.java:44)
at xml.anyattr.MyAnyAttrUtils.main(MyAnyAttrUtils.java:53)