单元测试中未解析xsd元素名称

时间:2016-10-19 10:04:24

标签: java xsd

我正在尝试在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源可能出错的建议吗?

1 个答案:

答案 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架构的系统。