Announcement

Collapse
No announcement yet.

XML-Validierung mit Java

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • XML-Validierung mit Java

    Hallo zusammen!

    Ich möchte gern XML-Dokumente anhand eines Schemas validieren. Dafür nutze ich momentan nutze ich die Funktionen aus den Packages "javax.xml" und "org.xml.sax". Ich arbeite mit einem ErrorHandler, der die Methoden error(), warning() und fatalError() implementiert. Das funktioniert soweit auch sehr gut.

    Mein Problem ist allerdings, daß innerhalb eines komplexen Elementes nur ein Fehler gefunden wird. Sobald der erste Fehler gefunden wurde springt er aus dem Element heraus und macht mit dem nächsten weiter.

    Beispiel:
    <ADRESSE>
    <STRASSE>EU/1/00/123/002</STRASSE>
    <HAUSNUMMER_Fehler1>51</HAUSNUMMER_Fehler1>
    <PLZ>100</PLZ>
    <ORT_Fehler2>20000</ORT_Fehler2>
    </ADRESSE>
    In diesem Fall findet er immer nur den "Fehler1". Wäre eine zweite Adressangabe vorhanden, würde er mit dieser fortfahren und dort genauso verfahren.

    Die Methoden des ErrorHandler sehen folgendermaßen aus, am Beispiel der error-Methode:
    Code:
    public void error( SAXParseException e )  {		
    		System.out.println("Error: "+e.toString());
    		System.out.println("Position:   +e.getColumnNumber()+"/"+e.getLineNumber());
    }
    Hat eventuell jemand eine Idee, wie ich ihn dazu veranlassen könnte wirklich alle Fehler zu registrieren?

    Vielen Dank schoneinmal
    MichaelPF

  • #2
    Siehe Doku
    Note, however, that there is no requirement that the parser continue to report additional errors after a call to fatalError.
    Christian

    Comment


    • #3
      Hallo,
      ersteinmal danke für die Antwort und es tut mir sehr leid, daß ich erst jetzt wieder reagiere.

      Die Validierung durchläuft das gesamte XML-Dokument bis zum Ende, ohne abzubrechen. Das ist daher nicht das Problem.
      Allerdings wird für jeden komplexen Typ immer nur ein Fehler angezeigt, auch wenn mehrere vorhanden sind. Ich würde gern alle Validierungsfehler sammeln und ausgeben können.
      An einem "fatalError" kann es meines Erachtens nach nicht liegen, weil laut meinem ErrorHandler nur einfache Fehler gemeldet werden.

      Comment


      • #4
        Zeige mal Programm, XML und Schema
        Christian

        Comment


        • #5
          Die Methode in der die Initialisierungen vorgenommen werden und die Validierung gestartet wird:

          Code:
          import javax.xml.XMLConstants;
          import javax.xml.transform.Source;
          import javax.xml.transform.stream.StreamSource;
          import javax.xml.validation.*;
          import org.xml.sax.ErrorHandler;
          import org.xml.sax.SAXException;
          
          public boolean validate() {
          		
          		//1. Schema factory
          		factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
          		
          		try {
          			//2. Compilierung des Schemas
          			schemaFile = new File(this.schemaFileName);
          			schemaSource = new StreamSource(schemaFile);
          			schema = factory.newSchema(schemaSource);
          			
          			// 3. Validator vom Schema beziehen
          			validator = schema.newValidator();
          			
          			//3a) Error-Handler anlegen
          			tamrErrorHandler = new TAMR_ErrorHandler(this);
          			this.validator.setErrorHandler(tamrErrorHandler);
          			
          			// 4. Zu prüfendes Dokument parsen
          			xmlFile = new File(this.xmlFileName);
          			xmlSource = new StreamSource(xmlFile);
          			
          			// 5. Starten der Validierung
          			validator.validate(xmlSource);
          			
          		} catch (SAXException e) {
          			e.printStackTrace();
          		}
          		catch(IOException ioex) {
          			System.out.println("Fehler beim Aufruf von "+this.xmlFileName);
          		}		
          
          	}
          Der ErrorHandler implementiert die Methoden zur Behandlung der verschiedenen Validierungsmeldungen:
          Code:
          public void fatalError( SAXParseException e ) {
          	System.out.println("FatalError: "+e.toString());
          	System.out.println("Position: "+e.getColumnNumber()+"/"+e.getLineNumber());
          }
          
          public void error( SAXParseException e )  {		
          	System.out.println("Error: "+e.toString());
          	System.out.println("Position: "+e.getColumnNumber()+"/"+e.getLineNumber());
          }
          	
          public void warning( SAXParseException e ) {
          	System.out.println("Warning: "+e.toString());
          	System.out.println("Position: "+e.getColumnNumber()+"/"+e.getLineNumber());
          }
          Für Testzwecke habe ich ein XML-File und ein dazugehöriges Schema aus einem Tutorial entnommen.
          Hier also mal das XML-File, die Validierung findet hier, wie gesagt, nur einen Fehler in jedem komplexem Typ. Ich habe einmal absichtlich Fehler eingebaut, um die Validierung zu testen.

          Code:
          <?xml version="1.0" encoding="UTF-8"?>
          <pp:ProductionPlant
          	xmlns="http://www.masterfacture.de/ProductionPlanning"
          	xmlns:pp="http://www.masterfacture.de/ProductionPlanning"
          	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          	xsi:schemaLocation="http://www.masterfacture.de/ProductionPlanning ProductionPlant.xsd"
          	pp:Description="A simple example plant">
          	<pp:Modules>
          		
          		<pp:Module pp:ID="Warehouse" pp:Type="HighBayWarehouse" />
          		<pp:Module pp:ID="Ramp" pp:Type="Ramp" />
          		
          		<pp:ModuleFEHLER1 pp:ID="C01" pp:Type="Conveyor" />
          		<pp:Module pp:ID="C02" pp:Type="Conveyor" />
          		<pp:Module pp:ID="C03" pp:Type="Conveyor" pp:Length="3" />
          		<pp:Module pp:ID="C04" pp:Type="Conveyor" pp:Length="2" />
          		<pp:Module pp:ID="C05" pp:Type="Conveyor" />
          		<pp:Module pp:ID="C06" pp:Type="Conveyor" />
          		<pp:Module pp:ID="C07" pp:Type="Conveyor" pp:Length="2" />
          		<pp:Module pp:ID="C08" pp:Type="Conveyor" />
          		<pp:ModuleFEHLER2 pp:ID="C09" pp:Type="Conveyor" pp:Length="2" />
          		<pp:Module pp:ID="C10" pp:Type="Conveyor" pp:Length="3" />
          		<pp:Module pp:ID="C11" pp:Type="Conveyor" />
          		<pp:Module pp:ID="C12" pp:Type="Conveyor" pp:Length="7" />
          		<pp:Module pp:ID="C13" pp:Type="Conveyor" pp:Length="5" />
          		<pp:Module pp:ID="C14" pp:Type="Conveyor" />
          		<pp:Module pp:ID="C15" pp:Type="Conveyor" pp:Length="5" />
          		<pp:Module pp:ID="C16" pp:Type="Conveyor" pp:Length="5" />
          		
          		<pp:Module pp:ID="StationA1" pp:Type="ProductionStation" />
          		<pp:Module pp:ID="StationA2" pp:Type="ProductionStation" />
          		<pp:Module pp:ID="StationB" pp:Type="ProductionStation" />
          
          		<pp:Module pp:ID="RP01" pp:Type="RotaryPlate" />
          		<pp:Module pp:ID="RP02" pp:Type="RotaryPlate" />
          		<pp:Module pp:ID="RP03" pp:Type="RotaryPlate" />
          		<pp:Module pp:ID="RP04" pp:Type="RotaryPlate" />
          		<pp:Module pp:ID="RP05" pp:Type="RotaryPlate" />
          		<pp:Module pp:ID="RP06" pp:Type="RotaryPlate" />
          		<pp:Module pp:ID="RP07" pp:Type="RotaryPlate" />
          		<pp:Module pp:ID="RP08" pp:Type="RotaryPlate" />
          		
          	</pp:Modules>
          	<pp:Connections>
          	
          		<pp:Connection pp:Module1="Warehouse" pp:Module2="C01" />
          		<pp:Connection pp:Module1="Warehouse" pp:Module2="C12" />
          		<pp:Connection pp:Module1="Ramp" pp:Module2="C08" />
          		
          		<pp:Connection pp:Module1="StationA1" pp:Module2="C15" />
          		<pp:Connection pp:Module1="StationA1" pp:Module2="C14" />
          		<pp:Connection pp:Module1="StationB" pp:Module2="C13" />
          		<pp:Connection pp:Module1="StationB" pp:Module2="C14" />
          		<pp:Connection pp:Module1="StationA2" pp:Module2="C05" />
          		<pp:Connection pp:Module1="StationA2" pp:Module2="C06" />
          		
          		<pp:Connection pp:Module1="RP01" pp:Module2="C16" />
          		<pp:ConnectionFEHLER1 pp:Module1="RP01" pp:Module2="C01" />
          		<pp:Connection pp:Module1="RP01" pp:Module2="C02" />
          		<pp:Connection pp:Module1="RP02" pp:Module2="C02" />
          		<pp:Connection pp:Module1="RP02" pp:Module2="C03" />
          		<pp:Connection pp:Module1="RP03" pp:Module2="C03" />
          		<pp:Connection pp:Module1="RP03" pp:Module2="C15" />
          		<pp:Connection pp:Module1="RP03" pp:Module2="C04" />
          		<pp:Connection pp:Module1="RP04" pp:Module2="C04" />
          		<pp:Connection pp:Module1="RP04" pp:Module2="C05" />
          		<pp:Connection pp:Module1="RP05" pp:Module2="C07" />
          		<pp:Connection pp:Module1="RP05" pp:Module2="C08" />
          		<pp:Connection pp:Module1="RP05" pp:Module2="C09" />
          		<pp:ConnectionFEHLER2 pp:Module1="RP06" pp:Module2="C09" />
          		<pp:Connection pp:Module1="RP06" pp:Module2="C10" />
          		<pp:Connection pp:Module1="RP06" pp:Module2="C13" />
          		<pp:Connection pp:Module1="RP07" pp:Module2="C10" />
          		<pp:Connection pp:Module1="RP07" pp:Module2="C11" />
          		<pp:Connection pp:Module1="RP08" pp:Module2="C11" />
          		<pp:Connection pp:Module1="RP08" pp:Module2="C12" />
          		<pp:Connection pp:Module1="RP08" pp:Module2="C16" />
          		
          		<pp:Connection pp:Module1="C06" pp:Module2="C07" />
          	</pp:Connections>
          </pp:ProductionPlant>
          Das Schema dazu sieht folgendermaßen aus:

          Code:
          <?xml version="1.0" encoding="UTF-8"?>
          <xsd:schema 
          	xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
          	elementFormDefault="qualified" 
          	attributeFormDefault="qualified" 
          	targetNamespace="http://www.masterfacture.de/ProductionPlanning" 
          	xmlns="http://www.masterfacture.de/ProductionPlanning"
          	xmlns:pp="http://www.masterfacture.de/ProductionPlanning">
          
          <xsd:element name="ProductionPlant">
          
          	<xsd:annotation>
          		<xsd:documentation>
          			A simple example schema for the configuration of a production plant
          			used by the PlantBuilder to create an object structure representing
          			a production plant.
          		</xsd:documentation>
          	</xsd:annotation>
          
          	<xsd:complexType>
          		<xsd:sequence>
          			<xsd:element name="Modules">
          				<xsd:complexType>
          					<xsd:sequence>
          						<xsd:element name="Module" type="Module" minOccurs="1" maxOccurs="unbounded" />
          					</xsd:sequence>
          				</xsd:complexType>
          			</xsd:element>
          			<xsd:element name="Connections">
          				<xsd:complexType>
          					<xsd:sequence>
          						<xsd:element name="Connection" type="Connection" minOccurs="0" maxOccurs="unbounded" />
          					</xsd:sequence>
          				</xsd:complexType>
          			</xsd:element>
          		</xsd:sequence>
          		<xsd:attribute name="Description" type="xsd:string" use="required" />
          	</xsd:complexType>
          
          	<xsd:unique name="ModuleIDs">
          		<xsd:selector xpath=".//pp:ProductionPlant/pp:Modules/pp:Module" />
          		<xsd:field xpath="@pp:ID" />
          	</xsd:unique>
          
          	<xsd:key name="ModuleID">
          		<xsd:selector xpath=".//pp:ProductionPlant/pp:Modules/pp:Module" />
          		<xsd:field xpath="@pp:ID" />
          	</xsd:key>
          	<xsd:keyref name="Module1Connection" refer="ModuleID">
          		<xsd:selector xpath=".//pp:ProductionPlant/pp:Connections/pp:Connection" />
          		<xsd:field xpath="@pp:Module1" />
          	</xsd:keyref>
          	<xsd:keyref name="Module2Connection" refer="ModuleID">
          		<xsd:selector xpath=".//pp:ProductionPlant/pp:Connections/pp:Connection" />
          		<xsd:field xpath="@pp:Module1" />
          	</xsd:keyref>
          	
          </xsd:element>
          
          <xsd:complexType name="Module">
          	<xsd:attribute name="ID" type="xsd:string" use="required" />
          	<xsd:attribute name="Type" type="ModuleType" use="required" />
          	<xsd:attribute name="Length" type="xsd:int" />
          </xsd:complexType>
          
          <xsd:simpleType name="ModuleType">
          	<xsd:restriction base="xsd:string">
          		<xsd:enumeration value="Conveyor" />
          		<xsd:enumeration value="RotaryPlate" />
          		<xsd:enumeration value="ProductionStation" />
          		<xsd:enumeration value="Trolley" />
          		<xsd:enumeration value="HighBayWarehouse" />
          		<xsd:enumeration value="Ramp" />
          	</xsd:restriction>
          </xsd:simpleType>
          
          <xsd:complexType name="Connection">
          	<xsd:attribute name="Module1" type="xsd:string" use="required" />
          	<xsd:attribute name="Module2" type="xsd:string" use="required" />
          </xsd:complexType>
          
          </xsd:schema>

          Comment


          • #6
            Wenn das nun keine fatal-Errors sind, sehe ich nicht, was man anders machen könnte
            Christian

            Comment


            • #7
              Habe das mal nachgestellt. Ja, es wird immer nur der erste Fehler angezeigt. Seltsamerweise arbeitet Netbean in der IDE genauso, wenn man da, das XML validieren lässt


              [highlight=java]

              SchemaFactory factory=SchemaFactory.newInstance(XMLConstants.W3C _XML_SCHEMA_NS_URI);
              try
              {
              Schema schema=factory.newSchema(new StreamSource(new File("g:\\ProductionPlant.xsd")));
              Validator validator=schema.newValidator();
              TAMR_ErrorHandler tamrErrorHandler=new TAMR_ErrorHandler();
              validator.setErrorHandler(tamrErrorHandler);
              validator.validate(new StreamSource(new File("g:\\test.xml")));
              }
              catch(SAXException|IOException e)
              {
              e.printStackTrace();
              }

              [/highlight]

              Es liegt dann wohl daran, wie der Parser arbeitet...
              Zuletzt editiert von Christian Marquardt; 14.11.2011, 18:57.
              Christian

              Comment

              Working...
              X