我正在尝试在junit单元测试中验证xml文件。这是我的简化代码。可以从http://www.unece.org/和http://www.gs1.org/
访问架构package test;
import java.net.URL;
import java.nio.file.Paths;
import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
public class Epcis11MessageCreatorForSoTest {
private static Schema schema;
private final static String[] XSD_FILES = {
"epcis11/xsd/BasicTypes.xsd",
"epcis11/xsd/DocumentIdentification.xsd",
"epcis11/xsd/Partner.xsd",
"epcis11/xsd/Manifest.xsd",
"epcis11/xsd/BusinessScope.xsd",
"epcis11/xsd/StandardBusinessDocumentHeader.xsd",
"epcis11/xsd/EPCglobal.xsd",
"epcis11/xsd/EPCglobal-epcis-1_1.xsd",
"epcis11/xsd/EPCglobal-epcis-query-1_1.xsd",
"epcis11/xsd/EPCglobal-epcis-masterdata-1_1.xsd",
};
@BeforeClass
public static void beforeClass() throws Exception {
try {
System.setProperty("jaxp.debug", "10");
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Source[] sources = new Source[XSD_FILES.length];
int i = 0;
for (String xsdfile : XSD_FILES) {
URL resource = Epcis11MessageCreatorForSoTest.class.getClassLoader().getResource(xsdfile);
String systemId = Paths.get(resource.toURI()).toFile().getAbsolutePath();
StreamSource ss = new StreamSource(
Epcis11MessageCreatorForSoTest.class.getClassLoader().getResourceAsStream(xsdfile),systemId);
sources[i] = ss;
i++;
}
schema = schemaFactory.newSchema(sources);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testFoo() {
Assert.assertTrue(true);
}
}
但由于以下原因未构建架构:
目标/测试类/ epcis11 / XSD / EPCglobal的-EPCIS-1_1.xsd; lineNumber:46; columnNumber:60; src-resolve:无法解析名称' sbdh:StandardBusinessDocumentHeader'到(n)'元素声明'成分
相关行看起来像这样(EPCglobal-epcis-1_1.xsd)
<xsd:schema xmlns:epcis="urn:epcglobal:epcis:xsd:1" xmlns:sbdh="http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader" xmlns:epcglobal="urn:epcglobal:xsd:1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:epcglobal:epcis:xsd:1" elementFormDefault="unqualified" attributeFormDefault="unqualified" version="1.1">
...
<xsd:import namespace="http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader" schemaLocation="./StandardBusinessDocumentHeader.xsd"/>
...
<xsd:element ref="sbdh:StandardBusinessDocumentHeader"/>
我使用Eclipse作为ide,项目使用JavaSE-1.7作为JRE系统库。在查看这些xsd文件时,它们在语法上是可以的。那就是我在ide中没有得到任何与xml相关的错误。当测试从ide内部或通过maven运行时,会出现完全相同的错误。
有关作为java对象的schemafactory或xsd源可能出错的建议吗?
答案 0 :(得分:0)
我很幸运有时间通过调试器运行我的代码。这是非常重的东西。例如,com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.class包含超过100个导入和超过4000行代码。
无论如何,我愿意认为com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLInputSource)中存在编程错误,该错误会加载xsd语法或模式或模式源。上下文。
为http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader命名空间加载的第一个语法是BasicTypes.xsd。
我的发现是,该语法是由其命名空间映射的,并且在它被其他模式包含之后,它以某种方式阻止了包含命名空间的包含者,语法被映射。我可以成功地将EPCglobal-epcis-1_1.xsd引用到BasicTypes.xsd中定义的任何类型,但引用http:/ /www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader命名空间中的任何其他元素或类型 not 会导致名称解析错误。
我的理论得到了支持,如果我将任何类型定义或元素声明移动到BasicTypes.xsd,我可以成功地将EPCglobal-epcis-1_1.xsd引用到该类型或元素。
事实上,我可以不情愿地将此项目中使用的名称空间http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader中的所有类型定义和元素声明合并到一个xsd源文件中,然后正确构建模式。
但由于我没有使用任何用于验证的xsd文件,这感觉就像某种黑客攻击。我宁愿使用一个可以从我的项目文件中构建xml架构的系统。