如何使用 Java 从 XSD 生成 XML 数据?
How to generate XML data from XSD using Java?
在我正在处理的应用程序中,我需要从 XSD 生成示例数据(XML 实例)。
我有 String
形式的 XSD,需要再次生成相应的 XML
作为 String
。
例如考虑以下 XSD
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Employee">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:byte" name="age"/>
<xs:element type="xs:string" name="role"/>
<xs:element type="xs:string" name="gender"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
我要生成
<Employee>
<name>string</name>
<age>2</age>
<role>string</role>
<gender>string</gender>
</Employee>
搜索了一段时间后,发现了各种在线工具可以做到这一点,但我希望能够使用 Java 来实现它。
还有像 Eclipse、Netbeans、IntelliJ 这样的 IDE 能够实现所需的功能,除了它们依赖于 XSD 作为文件给出。
经过一番搜索,似乎大多数都使用 Apache XMLBeans。
我试着按照安装指南设置了下面提到的所有环境变量
export XMLBEANS_HOME=/home/user/Programs/xmlbeans-3.1.0
PATH=$PATH:$XMLBEANS_HOME/bin
export CLASSPATH=$XMLBEANS_HOME/lib/xmlbeans-3.1.0.jar:$CLASSPATH
export XMLBEANS_LIB=/home/user/Programs/xmlbeans-3.1.0/lib/xmlbeans-3.1.0.jar
毕竟如果我运行下面给出的命令
./xsd2inst ../../Schema.xsd
我收到错误
Error: Could not find or load main class org.apache.xmlbeans.impl.xsd2inst.SchemaInstanceGenerator
问题:
- 我该如何解决这个错误?
- 如果我得到这个工作,我可能可以在将 XSD 字符串写入文件后从 java 进程调用此命令并将其作为参数传递给命令,就像我有如上所示。但我不认为这是一个优雅的解决方案,还有其他方法可以完成我提到的吗?
注:
- 我不能使用任何商业广告products/libraries。
- 我知道使用 JAXB,但这需要我创建一个 POJO
对于我想要为其生成数据的类型不是
我可以做到,因为 XSD 数据是动态的,我不能重复使用那些
POJO 即使我创建它也是如此。
深入挖掘后,发现 XMLBEANS_LIB
的环境变量值设置错误。 XMLBEANS_LIB
期望指向 XML Beans 分发的 lib
目录而不是 xmlbeans-3.1.0.jar
。所以正确的值是
export XMLBEANS_LIB=/home/user/Programs/xmlbeans-3.1.0/lib
我能够使用下面的代码使用 XSD(作为字符串给出)生成 XML实例(作为字符串)。
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeSystem;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.impl.xsd2inst.SampleXmlUtil;
import org.apache.xmlbeans.impl.xsd2inst.SchemaInstanceGenerator;
import java.util.ArrayList;
import java.util.List;
public class XmlInstanceGeneratorImpl {
private static final Logger logger = LogManager.getLogger(XmlInstanceGeneratorImpl.class);
/**
* Specifies if network downloads are enabled for imports and includes.
* Default value is {@code false}
*/
private static final boolean ENABLE_NETWORK_DOWNLOADS = false;
/**
* disable particle valid (restriction) rule
* Default value is {@code false}
*/
private static final boolean NO_PVR = false;
/**
* disable unique particle attribution rule.
* Default value is {@code false}
*/
private static final boolean NO_UPA = false;
public String generateXmlInstance(String xsdAsString, String elementToGenerate){
return generateXmlInstance(xsdAsString, elementToGenerate, ENABLE_NETWORK_DOWNLOADS, NO_PVR, NO_UPA);
}
public String generateXmlInstance(String xsAsString, String elementToGenerate, boolean enableDownloads,
boolean noPvr, boolean noUpa){
List<XmlObject> schemaXmlObjects = new ArrayList<>();
try {
schemaXmlObjects.add(XmlObject.Factory.parse(xsAsString));
} catch (XmlException e) {
logger.error("Error Occured while Parsing Schema",e);
}
XmlObject[] xmlObjects = schemaXmlObjects.toArray(new XmlObject[1]);
SchemaInstanceGenerator.Xsd2InstOptions options = new SchemaInstanceGenerator.Xsd2InstOptions();
options.setNetworkDownloads(enableDownloads);
options.setNopvr(noPvr);
options.setNoupa(noUpa);
return xsd2inst(xmlObjects, elementToGenerate, options);
}
private String xsd2inst(XmlObject[] schemas, String rootName, SchemaInstanceGenerator.Xsd2InstOptions options){
SchemaTypeSystem schemaTypeSystem = null;
if (schemas.length > 0) {
XmlOptions compileOptions = new XmlOptions();
if (options.isNetworkDownloads())
compileOptions.setCompileDownloadUrls();
if (options.isNopvr())
compileOptions.setCompileNoPvrRule();
if (options.isNoupa())
compileOptions.setCompileNoUpaRule();
try {
schemaTypeSystem = XmlBeans.compileXsd(schemas, XmlBeans.getBuiltinTypeSystem(), compileOptions);
} catch (XmlException e) {
logger.error("Error occurred while compiling XSD",e);
}
}
if (schemaTypeSystem == null) {
throw new RuntimeException("No Schemas to process.");
}
SchemaType[] globalElements = schemaTypeSystem.documentTypes();
SchemaType elem = null;
for (SchemaType globalElement : globalElements) {
if (rootName.equals(globalElement.getDocumentElementName().getLocalPart())) {
elem = globalElement;
break;
}
}
if (elem == null) {
throw new RuntimeException("Could not find a global element with name \"" + rootName + "\"");
}
// Now generate it and return the result
return SampleXmlUtil.createSampleForType(elem);
}
}
在我正在处理的应用程序中,我需要从 XSD 生成示例数据(XML 实例)。
我有 String
形式的 XSD,需要再次生成相应的 XML
作为 String
。
例如考虑以下 XSD
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Employee">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:byte" name="age"/>
<xs:element type="xs:string" name="role"/>
<xs:element type="xs:string" name="gender"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
我要生成
<Employee>
<name>string</name>
<age>2</age>
<role>string</role>
<gender>string</gender>
</Employee>
搜索了一段时间后,发现了各种在线工具可以做到这一点,但我希望能够使用 Java 来实现它。 还有像 Eclipse、Netbeans、IntelliJ 这样的 IDE 能够实现所需的功能,除了它们依赖于 XSD 作为文件给出。
经过一番搜索,似乎大多数都使用 Apache XMLBeans。
我试着按照安装指南设置了下面提到的所有环境变量
export XMLBEANS_HOME=/home/user/Programs/xmlbeans-3.1.0
PATH=$PATH:$XMLBEANS_HOME/bin
export CLASSPATH=$XMLBEANS_HOME/lib/xmlbeans-3.1.0.jar:$CLASSPATH
export XMLBEANS_LIB=/home/user/Programs/xmlbeans-3.1.0/lib/xmlbeans-3.1.0.jar
毕竟如果我运行下面给出的命令
./xsd2inst ../../Schema.xsd
我收到错误
Error: Could not find or load main class org.apache.xmlbeans.impl.xsd2inst.SchemaInstanceGenerator
问题:
- 我该如何解决这个错误?
- 如果我得到这个工作,我可能可以在将 XSD 字符串写入文件后从 java 进程调用此命令并将其作为参数传递给命令,就像我有如上所示。但我不认为这是一个优雅的解决方案,还有其他方法可以完成我提到的吗?
注:
- 我不能使用任何商业广告products/libraries。
- 我知道使用 JAXB,但这需要我创建一个 POJO 对于我想要为其生成数据的类型不是 我可以做到,因为 XSD 数据是动态的,我不能重复使用那些 POJO 即使我创建它也是如此。
深入挖掘后,发现 XMLBEANS_LIB
的环境变量值设置错误。 XMLBEANS_LIB
期望指向 XML Beans 分发的 lib
目录而不是 xmlbeans-3.1.0.jar
。所以正确的值是
export XMLBEANS_LIB=/home/user/Programs/xmlbeans-3.1.0/lib
我能够使用下面的代码使用 XSD(作为字符串给出)生成 XML实例(作为字符串)。
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeSystem;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.impl.xsd2inst.SampleXmlUtil;
import org.apache.xmlbeans.impl.xsd2inst.SchemaInstanceGenerator;
import java.util.ArrayList;
import java.util.List;
public class XmlInstanceGeneratorImpl {
private static final Logger logger = LogManager.getLogger(XmlInstanceGeneratorImpl.class);
/**
* Specifies if network downloads are enabled for imports and includes.
* Default value is {@code false}
*/
private static final boolean ENABLE_NETWORK_DOWNLOADS = false;
/**
* disable particle valid (restriction) rule
* Default value is {@code false}
*/
private static final boolean NO_PVR = false;
/**
* disable unique particle attribution rule.
* Default value is {@code false}
*/
private static final boolean NO_UPA = false;
public String generateXmlInstance(String xsdAsString, String elementToGenerate){
return generateXmlInstance(xsdAsString, elementToGenerate, ENABLE_NETWORK_DOWNLOADS, NO_PVR, NO_UPA);
}
public String generateXmlInstance(String xsAsString, String elementToGenerate, boolean enableDownloads,
boolean noPvr, boolean noUpa){
List<XmlObject> schemaXmlObjects = new ArrayList<>();
try {
schemaXmlObjects.add(XmlObject.Factory.parse(xsAsString));
} catch (XmlException e) {
logger.error("Error Occured while Parsing Schema",e);
}
XmlObject[] xmlObjects = schemaXmlObjects.toArray(new XmlObject[1]);
SchemaInstanceGenerator.Xsd2InstOptions options = new SchemaInstanceGenerator.Xsd2InstOptions();
options.setNetworkDownloads(enableDownloads);
options.setNopvr(noPvr);
options.setNoupa(noUpa);
return xsd2inst(xmlObjects, elementToGenerate, options);
}
private String xsd2inst(XmlObject[] schemas, String rootName, SchemaInstanceGenerator.Xsd2InstOptions options){
SchemaTypeSystem schemaTypeSystem = null;
if (schemas.length > 0) {
XmlOptions compileOptions = new XmlOptions();
if (options.isNetworkDownloads())
compileOptions.setCompileDownloadUrls();
if (options.isNopvr())
compileOptions.setCompileNoPvrRule();
if (options.isNoupa())
compileOptions.setCompileNoUpaRule();
try {
schemaTypeSystem = XmlBeans.compileXsd(schemas, XmlBeans.getBuiltinTypeSystem(), compileOptions);
} catch (XmlException e) {
logger.error("Error occurred while compiling XSD",e);
}
}
if (schemaTypeSystem == null) {
throw new RuntimeException("No Schemas to process.");
}
SchemaType[] globalElements = schemaTypeSystem.documentTypes();
SchemaType elem = null;
for (SchemaType globalElement : globalElements) {
if (rootName.equals(globalElement.getDocumentElementName().getLocalPart())) {
elem = globalElement;
break;
}
}
if (elem == null) {
throw new RuntimeException("Could not find a global element with name \"" + rootName + "\"");
}
// Now generate it and return the result
return SampleXmlUtil.createSampleForType(elem);
}
}