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>
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
@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
@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