我们正在开发一个涉及大量XML转换的应用程序。我们没有任何适当的输入测试数据,只有DTD或XSD文件。我们希望从这些文件中自己生成测试数据。是否有一种简单/免费的方法可以做到这一点?
编辑
显然没有免费的工具可供使用,我同意OxygenXML是其中最好的工具之一。
在Visual Studio 2008 SP1及更高版本中,XML Schema Explorer可以创建一个带有基本示例数据的XML文档:
xsd:choice
,那么示例 XML 文件只能包含该选择中的一个。https://msdn.microsoft.com/zh-cn/library/ms256109(v=vs.110).aspx - Davos在最新版本的免费开源Eclipse IDE中,您可以从DTD和XSD文件生成XML文档。右键单击特定的*.dtd或*.xsd文件,选择“生成-> XML文件...”。您可以选择要生成哪个根元素以及是否应生成可选属性和元素。
当然,您也可以使用Eclipse创建和编辑您的DTD和XSD模式文件,无需安装任何插件。它已包含在标准发行版中。
对于Intellij Idea用户:
点击"工具"-> "XML操作"
据我所测试,它似乎运行的非常好。
编辑:
正如@naXa所提到的,您现在还可以右键单击XSD文件并单击“从XSD模式生成XML文档...”
我认为 Oxygen (http://www.oxygenxml.com/) 也可以实现这个功能,但那是另一个商业产品。不过它很不错... 我强烈建议所有从事大量XML工作的人使用该产品。它还有一个很好的Eclipse插件。
我相信有一个免费的、完整功能的30天试用期。
xmlgen.zip
,然后运行以下命令以获取详细的使用说明:
该工具似乎是根据BSD许可证发布的;源代码可以从这里访问。
java -jar xmlgen.jar -help
XMLSpy 可以为您完成这项工作,但需要付费...
我相信 Liquid Xml Studio 可以为您完成这项工作并且是免费的,但我个人没有使用它来创建测试数据。
目前似乎没有人能够回答这个问题 :)
我使用EclipseLink的MOXy动态生成绑定类,然后递归遍历绑定类型。这有点重,但一旦对象树实例化,它允许XPath值注入:
InputStream in = new FileInputStream(PATH_TO_XSD);
DynamicJAXBContext jaxbContext =
DynamicJAXBContextFactory.createContextFromXSD(in, null, Thread.currentThread().getContextClassLoader(), null);
DynamicType rootType = jaxbContext.getDynamicType(YOUR_ROOT_TYPE);
DynamicEntity root = rootType.newDynamicEntity();
traverseProps(jaxbContext, root, rootType, 0);
TraverseProps是一个相当简单的递归方法:
private void traverseProps(DynamicJAXBContext c, DynamicEntity e, DynamicType t, int level) throws DynamicException, InstantiationException, IllegalAccessException{
if (t!=null) {
logger.info(indent(level) + "type [" + t.getName() + "] of class [" + t.getClassName() + "] has " + t.getNumberOfProperties() + " props");
for (String pName:t.getPropertiesNames()){
Class<?> clazz = t.getPropertyType(pName);
logger.info(indent(level) + "prop [" + pName + "] in type: " + clazz);
//logger.info("prop [" + pName + "] in entity: " + e.get(pName));
if (clazz==null){
// need to create an instance of object
String updatedClassName = pName.substring(0, 1).toUpperCase() + pName.substring(1);
logger.info(indent(level) + "Creating new type instance for " + pName + " using following class name: " + updatedClassName );
DynamicType child = c.getDynamicType("generated." + updatedClassName);
DynamicEntity childEntity = child.newDynamicEntity();
e.set(pName, childEntity);
traverseProps(c, childEntity, child, level+1);
} else {
// just set empty value
e.set(pName, clazz.newInstance());
}
}
} else {
logger.warn("type is null");
}
}
将所有内容转换为XML格式非常简单:
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);