2016-10-19 1 views
0

Ich versuche XML-Dateien in einem Junit-Unit-Test zu validieren. Dies ist mein vereinfachter Code. Schemen sind von http://www.unece.org/ und http://www.gs1.org/Name des xsd-Elements im Komponententest nicht aufgelöst

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); 
    } 

} 

jedoch das Schema aufgrund nicht gebaut wird:

Ziel/Test-Klassen/epcis11/XSD/EPCglobal-EPCIS-1_1.xsd; Zeilennummer: 46; Spaltennummer: 60; src-resolve: Der Name 'sbdh: StandardBusinessDocumentHeader' kann nicht in eine (n) Element-Deklarationskomponente aufgelöst werden.

Relevante Zeilen wie folgt aussehen (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"/> 

Ich benutze Eclipse als ein IDE-und Projekt verwendet JavaSE-1.7 als JRE System Library. Beim Betrachten dieser xsd-Dateien sind sie syntaktisch in Ordnung. Das heißt, ich bekomme keine XML-bezogenen Fehler in IDE. Genau derselbe Fehler tritt auf, wenn der Test entweder innerhalb von ide oder über maven ausgeführt wird.

Irgendwelche Vorschläge darüber, was mit meinen Schemafactory- oder xsd-Quellen als Java-Objekte falsch sein könnte?

+0

wo ist der Namespace 'sbdh' definiert? –

+0

Das Namespacepräfix 'sbdh' befindet sich in EPCglobal-epcis-1_1.xsd. Es gibt einen Ausschnitt der obigen Zeile. – user7040845

Antwort

0

Ich hatte das Glück, meinen Code über einen Debugger laufen zu lassen. Es war ziemlich schweres Zeug. Zum Beispiel enthält com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.class mehr als 100 Importe und über 4000 Codezeilen.

Jedenfalls bin ich bereit zu denken, dass es in com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar (XMLInputSource) einen Programmierfehler gibt, der xsd-Grammatiken oder Schemas oder Schemasources lädt unser Kontext.

Erste Grammatik geladen für http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader Namespace ist BasicTypes.xsd.

Meine Ergebnisse sind, dass Grammatik wird durch seinen Namespace zugeordnet und nachdem es von anderen Schemas enthalten ist es irgendwie prevententing die Includers ', die den Namespace teilen, Grammatik aus zugeordnet werden. Ich kann erfolgreich von EPCglobal-epcis-1_1.xsd auf jeden Typ verweisen, der in BasicTypes.xsd definiert ist, aber auf ein anderes Element oder einen anderen Typ im http: //www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader-Namespace verweisen, der nicht lautet definiert in BasicTypes.xsd führt zu einem Namensauflösungsfehler.

Meine Theorie ist dadurch gesichert, dass ich, wenn ich eine Typdefinition oder Elementdeklaration nach BasicTypes.xsd verschiebe, erfolgreich von EPCglobal-epcis-1_1.xsd auf diesen Typ oder Element verweisen kann.

Tatsächlich kann ich, willentlich, alle Typdefinitionen und Elementdeklarationen in Namespace http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader, die in diesem Projekt in einer xsd-Quelldatei verwendet werden, konsolidieren, und dann wird das Schema korrekt erstellt.

Da aber keine der für die Validierung verwendeten xsd-Dateien von mir gepflegt wird, fühlt sich das wie eine Art Hack an. Ich würde lieber ein System verwenden, das aus meinen Projektdateien ein XML-Schema erstellen kann.

+0

Im Zusammenhang mit diesem Problem ist jetzt ein von Oracle genehmigter Fehler: http://bugs.java.com/bugdatabase/view_bug.do? bug_id = JDK-8168883 – user7040845

Verwandte Themen