2011-01-16 13 views
2

Ich benutze Xalan 2.7.1, um meine XML-Dokumente mit XSLT-Stylesheet zu validieren. Es funktioniert gut für das erste Dokument und gibt Fehlermeldung im Fehlerfall zusammen mit der richtigen Zeilen- und Spaltennummer der XML-Quelle zurück, indem die Erweiterungen NodeInfo.lineNumber und NodeInfo.columnNumber verwendet werden.Wiederverwendung von Xalan-Transformator, der seine Erweiterungsfunktionen verursacht break

Das Problem ist, wenn ich versuche, Transformator erneut zu validieren, um andere XML-Dokumente zu validieren, es das Dokument erfolgreich umwandelt, aber LineNumber = columnNumber = -1 immer für alle Fehler zurückgibt.
Irgendeine Idee?

Edit: Hier ist mein Code ::

package mycompany; 

import java.io.File; 
import javax.xml.transform.ErrorListener; 
import javax.xml.transform.Source; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.transform.stream.StreamSource; 
import org.apache.xalan.processor.TransformerFactoryImpl; 

public class XsltTransformer { 

    public static void main(String[] args) { 

     TransformerFactory tFactory = TransformerFactory.newInstance(); 
     tFactory.setAttribute(TransformerFactoryImpl.FEATURE_SOURCE_LOCATION, Boolean.TRUE); 

     StreamSource xsltStreamSource = new StreamSource(new File("E:\\Temp\\Test\\myXslt.xsl")); 
     try { 
      Transformer transformer = tFactory.newTransformer(xsltStreamSource); 

      File srcFolder = new File("E:\\Temp\\Test"); 
      for (File file : srcFolder.listFiles()) { 
       if (file.getName().endsWith("xml")) { 

        Source source = new StreamSource(file); 
        StreamResult result = new StreamResult(System.out); 

        XsltTransformer xsltTransformer = new XsltTransformer(); 
        ErrorListenerImpl errorHandler = xsltTransformer.new ErrorListenerImpl(); 
        transformer.setErrorListener(errorHandler); 

        transformer.transform(source, result); 

        if (errorHandler.e != null) { 
         System.out.println("Transformation Exception: " + errorHandler.e.getMessage()); 
        } 

        transformer.reset(); 
       } 
      } 

     } catch (TransformerException e) { 
      e.printStackTrace(); 
     } 
    } 

    private class ErrorListenerImpl implements ErrorListener { 
     public TransformerException e = null; 

     public void error(TransformerException exception) { 
      this.e = exception; 
     } 

     public void fatalError(TransformerException exception) { 
      this.e = exception; 
     } 

     public void warning(TransformerException exception) { 
      this.e = exception; 
     } 
    } 
} 

Edit: Hier sind myXslt.xsl und XML-Quellen:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<axsl:stylesheet 
    xmlns:axsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:iso="http://purl.oclc.org/dsdl/schematron" 
    xmlns:sch="http://www.ascc.net/xml/schematron" 
    version="1.0" 
    xmlns:nodeinfo="xalan://org.apache.xalan.lib.NodeInfo"> 

    <axsl:output 
     xmlns:svrl="http://purl.oclc.org/dsdl/svrl" 
     xmlns:schold="http://www.ascc.net/xml/schematron" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     indent="yes" 
     standalone="yes" 
     omit-xml-declaration="no" 
     method="xml" /> 

    <!--SCHEMA METADATA --> 
    <axsl:template match="/"> 
    <svrl:schematron-output xmlns:svrl="http://purl.oclc.org/dsdl/svrl" xmlns:schold="http://www.ascc.net/xml/schematron" 
          xmlns:xs="http://www.w3.org/2001/XMLSchema" schemaVersion="ISO19757-3" title="Test ISO schematron file. Introduction mode "> 
     <svrl:active-pattern> 
     <axsl:apply-templates /> 
     </svrl:active-pattern> 
     <axsl:apply-templates mode="M1" select="/" /> 
    </svrl:schematron-output> 
    </axsl:template> 

    <!--RULE --> 
    <axsl:template mode="M1" priority="1000" match="//*[@remote-property]"> 
    <svrl:fired-rule xmlns:svrl="http://purl.oclc.org/dsdl/svrl" xmlns:schold="http://www.ascc.net/xml/schematron" 
        xmlns:xs="http://www.w3.org/2001/XMLSchema" context="//*[@remote-property]" /> 

    <!--ASSERT --> 
    <axsl:choose> 
     <axsl:when test="@remote-property = //@id or @remote-property = //@name" /> 
     <axsl:otherwise> 
     <svrl:failed-assert xmlns:svrl="http://purl.oclc.org/dsdl/svrl" xmlns:schold="http://www.ascc.net/xml/schematron" 
          xmlns:xs="http://www.w3.org/2001/XMLSchema" test="@remote-property = //@id or @remote-property = //@name"> 
      <axsl:attribute name="lineNumber"> 
       <axsl:value-of select="nodeinfo:lineNumber()" /> 
      </axsl:attribute> 
      <axsl:attribute name="columnNumber"> 
       <axsl:value-of select="nodeinfo:columnNumber()" /> 
      </axsl:attribute> 
      <svrl:text> 
      Invalid remote-property: remote class element with this id or name does not exists 
     </svrl:text> 
     </svrl:failed-assert> 
     </axsl:otherwise> 
    </axsl:choose> 
    </axsl:template> 
</axsl:stylesheet> 

source1.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <remote-service> 
     <class name="Table1" table="table1"> 
      <id name="col1"/> 
      <property name="col2"/> 
     </class> 
    </remote-service> 
    <application> 
     <text-field name="field1" remote-property="col1X"/> 
    </application> 
</root> 

und source2.xml

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <application> 
     <text-field name="field1" remote-property="col1Z"/> 
    </application> 
</root> 

Antwort

1

Die javadoc Staaten:

Der Reset-Transformator nicht garantiert ist Sie

die gleiche URIResolver oder ErrorListener Objekte haben, müssen unter Umständen Ihr ErrorListener Verweis auf die neue zurücksetzen ErrorListener des Rücksetztransformators.

Update

Ich habe keine Erfahrung mit der Schematron Bibliothek, von dem, was ich sehe es wohl ein Problem dieser Bibliothek ist durch einen Reset Transformator verwendet wird.

Wenn Sie es nicht an der Arbeit Zurücksetzen des Transformator Sie fähig sein könnte, die XSL-Vorlage Anlage verwenden zu müssen, um zu verhindern XSL Blatt auf jedem transorm zu interpretieren:

import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.Templates; 
import javax.xml.transform.Transformer; 

TransformerFactory factory = TransformerFactory.newInstance(); 

Templates xslTemplate = factory.newTemplates(new StreamSource(new StringReader(xsl))); 

später wieder verwenden, um die Vorlage von den Transformator daraus bekommen:

Transformer transformer = xslTemplate.newTransformer(); 
+0

Danke @rsp: es macht Sinn, aber es hat das Problem nicht gelöst. Würdest du bitte einen neuen Code sehen, der in der Originalfrage angehängt ist, um zu sehen, ob ich einen Fehler mache? – WSK

+1

@Leslie Norman, ich kann nicht helfen, aber beachte, dass du 2 Argumente an 'TransformerFactory.newInstance()' übergibst, wo das xalan javadoc für 2.7.1 nur eine 'newInstance() 'Methode ohne Argumente auflistet. Mischen Sie 2 Implementierungen? – rsp

+0

@rs: Ich habe Saxon parallel getestet, aber nicht mehr. Im vorliegenden Szenario sind diese Argumente also nur redundant, ohne einen Unterschied zu machen. Ich habe den Code nach dem Testen erneut aktualisiert. – WSK