在安全模式下使用Xalan执行XSLT以创建XHTML,在创建属性时会抛出TransformerConfiguratio



我试图在安全模式下使用更新版本的Xalan(2.7.2),并且无法理解未知属性。问题是,它阻止您使用任何发出XHTML的样式表(在安全处理模式下),因为它不允许"th"元素的"colspan"属性之类的东西。

相关的修改文件在这里:http://svn.apache.org/viewvc/xalan/java/branches/xalan-j_2_7_1_maint/src/org/apache/xalan/processor/XSLTElementProcessor.java?r1=1359736&r2=1581058&pathrev=1581058&diff_format=h

请看下面的例子:

import javax.xml.XMLConstants;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamSource;
import java.io.StringReader;
public class XalanSecureAttributeRepro {
    private static final String XSL =
            "<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">n" +
            "  <xsl:output method="html"/>n" +
            "  <xsl:template match="/*">n" +
            "    <th colspan="2"/>n" +
            "  </xsl:template>n" +
            "</xsl:stylesheet>";
    public static void main( String[] args ) throws Exception {
        System.setProperty( "javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl" );
        TransformerFactory tf = TransformerFactory.newInstance();
        tf.setFeature( XMLConstants.FEATURE_SECURE_PROCESSING, true);
        tf.setErrorListener( new DefaultErrorHandler( true ) );
        final Source source = new StreamSource( new StringReader( XSL ) );
        Templates templates = tf.newTemplates( source ); // throws:
                        // TransformerException: "colspan" attribute is not allowed on the th element!
    }
}

返回以下错误:

Exception in thread "main" javax.xml.transform.TransformerConfigurationException: javax.xml.transform.TransformerException: org.xml.sax.SAXException: "colspan" attribute is not allowed on the th element!
javax.xml.transform.TransformerException: "colspan" attribute is not allowed on the th element!
    at org.apache.xalan.processor.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:933)
    at com.l7tech.example.XalanSecureAttributeRepro.main(XalanSecureAttributeRepro.java:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: javax.xml.transform.TransformerException: org.xml.sax.SAXException: "colspan" attribute is not allowed on the th element!
javax.xml.transform.TransformerException: "colspan" attribute is not allowed on the th element!
    at org.apache.xalan.processor.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:925)
    ... 6 more
Caused by: org.xml.sax.SAXException: "colspan" attribute is not allowed on the th element!
javax.xml.transform.TransformerException: "colspan" attribute is not allowed on the th element!
    at org.apache.xalan.processor.StylesheetHandler.error(StylesheetHandler.java:919)
    at org.apache.xalan.processor.StylesheetHandler.error(StylesheetHandler.java:947)
    at org.apache.xalan.processor.XSLTElementProcessor.setPropertiesFromAttributes(XSLTElementProcessor.java:347)
    at org.apache.xalan.processor.XSLTElementProcessor.setPropertiesFromAttributes(XSLTElementProcessor.java:267)
    at org.apache.xalan.processor.ProcessorLRE.startElement(ProcessorLRE.java:283)
    at org.apache.xalan.processor.StylesheetHandler.startElement(StylesheetHandler.java:623)
    at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
    at org.apache.xerces.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at org.apache.xalan.processor.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:917)
    ... 6 more
Caused by: javax.xml.transform.TransformerException: "colspan" attribute is not allowed on the th element!
    at org.apache.xalan.processor.StylesheetHandler.error(StylesheetHandler.java:904)
    ... 22 more

是我在样式表上做错了什么,还是我错过了在转换器工厂上设置一个特性?如何使用Xalan转换在安全处理模式下发出(X)HTML的样式表?

所引用的Xalan源代码版本中有问题的行是:

if(attrDef.getName().compareTo("*")==0 && handler.getStylesheetProcessor().isSecureProcessing())

我不能100%确定attrDef是什么,但我猜这是你的属性,它永远不会有*的值(但从XSLTAttributeDef的文档中,值*是允许的,但我不知道如何,因为它不是qname)。

关于安全处理的文档只限制了单个元素上的属性数量,但是这个限制很高,有10,000个。

在我看来,你碰到了Xalan 2.7.1的一个bug。它阻止您使用任何属性。如果因为只能使用已知属性而施加限制,那么它似乎仍然是一个错误,因为th在HTML和XHTML中都允许将colspan作为属性。但是,如果您将输出从HTML更改为XML,您可能会看到相同的行为。

这是一个在Apache Servicemix构建的Xalan-2.7.2_3中解决的错误。

<dependency>
    <groupId>org.apache.servicemix.bundles</groupId>
    <artifactId>org.apache.servicemix.bundles.xalan</artifactId>
    <version>2.7.2_3</version><!--$NO-MVN-MAN-VER$-->
</dependency>

使用<!--$NO-MVN-MAN-VER$-->可以防止覆盖。

注意注意,这个错误修复是不是添加到Apache Xalan-2.7.3

<!-- https://mvnrepository.com/artifact/xalan/xalan -->
<dependency>
    <groupId>xalan</groupId>
    <artifactId>xalan</artifactId>
    <version>2.7.3</version>
</dependency>

最新更新