XSLT 在 Saxon 中生成带有未声明名称空间前缀的输出。错误 XTSE1430:命名空间前缀 exsl 未声明

XSLT generates output with undeclared namespace prefix in Saxon. error XTSE1430: Namespace prefix exsl is undeclared

我正在尝试针对 XML 实例验证 Yang 模型。我发现这个 bash 脚本[1] 可以完成这项工作,但我想使用 Java.

重写它

撒克逊版本

Saxon 9.9.1-5.

xsltproc 版本

Using libxml 20904, libxslt 10129 and libexslt 817

使用 Bash 中的 xsltproc,以下命令成功并生成一个有效的 xml,sch2,其中包含 exslt 命名空间。

xsltproc -o output1 iso_abstract_expand.xsl example.sch
xsltproc -o sch iso_svrl_for_xslt1.xsl output1
xsltproc -o sch2 sch inst

当我在 Java 中重写上述命令时,我得到

Static error at xsl:stylesheet on line 17 column 31 
XTSE1430: Namespace prefix exsl is undeclared

Java代码

class Test {
    public static StringBuffer transform(Source xsltSource, Source xmlSource) throws TransformerException {
        TransformerFactory transFact = new TransformerFactoryImpl();
        StringWriter sw = new StringWriter();
        Result result = new StreamResult(sw);
        Transformer transformer = transFact.newTransformer(xsltSource);
        transformer.transform(xmlSource, result);
        return sw.getBuffer();
    }

    public static StringBuffer xsltproc(String xslt, String xml) throws TransformerException {
        return transform(
                new StreamSource(new File(xslt)),
                new StreamSource(new File(xml))
        );
    }

    public static StringBuffer xsltproc(String xslt, StringBuffer xml) throws IOException, TransformerException {
        return transform(
                new StreamSource(new File(xslt)),
                new StreamSource(IOUtils.toInputStream(xml))
        );
    }

    public static StringBuffer xsltproc(StringBuffer xslt, String xml) throws IOException, TransformerException {
        return transform(
                new StreamSource(IOUtils.toInputStream(xslt)),
                new StreamSource(new File(xml))
        );
    }

    public static void main(String args[]) {
        try {
            StringBuffer output1 = xsltproc("iso_abstract_expand.xsl", "example.sch");
            StringBuffer sch = xsltproc("iso_svrl_for_xslt1.xsl", output1);
            StringBuffer sch = xsltproc(sch, "inst");
        }
        catch (Exception e) {
            e.printStackTrace();
        }

    }
}

其中 "iso_abstract_expand.xsl"、"example.sch"、"iso_svrl_for_xslt1.xsl"、"inst" 是磁盘上与上述文件位于同一文件夹中的文件 Java class.

iso_abstract_expand.xsl

https://github.com/mbj4668/pyang/blob/master/xslt/iso_abstract_expand.xsl

iso_svrl_for_xslt1.xsl

https://github.com/mbj4668/pyang/blob/master/xslt/iso_svrl_for_xslt1.xsl

example.sch

<?xml version="1.0" encoding="utf-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="exslt"><sch:ns uri="http://exslt.org/dynamic" prefix="dyn"/><sch:ns uri="http://example.net/turing-machine" prefix="tm"/><sch:ns uri="urn:ietf:params:xml:ns:netconf:base:1.0" prefix="nc"/><sch:let name="root" value="/nc:config"/><sch:pattern abstract="true" id="turing-machine___tape-cells"><sch:rule context="$start/$pref:cell"><sch:report test="preceding-sibling::$pref:cell[$pref:coord=current()/$pref:coord]">Duplicate key "coord"</sch:report></sch:rule></sch:pattern><sch:pattern id="turing-machine"><sch:rule context="/nc:config/tm:turing-machine/tm:transition-function/tm:delta"><sch:report test="preceding-sibling::tm:delta[tm:label=current()/tm:label]">Duplicate key "tm:label"</sch:report><sch:report test="preceding-sibling::tm:delta[tm:input/tm:state=current()/tm:input/tm:state and tm:input/tm:symbol=current()/tm:input/tm:symbol]">Violated uniqueness for "tm:input/tm:state tm:input/tm:symbol"</sch:report></sch:rule></sch:pattern><sch:pattern id="idm14" is-a="turing-machine___tape-cells"><sch:param name="start" value="/nc:config/tm:turing-machine/tm:tape"/><sch:param name="pref" value="tm"/></sch:pattern></sch:schema>

研究所

<?xml version="1.0" encoding="utf-8"?>
<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><turing-machine xmlns="http://example.net/turing-machine"><transition-function><delta><label>left summand</label><input><state>0</state><symbol>1</symbol></input><tm:output xmlns:tm="http://example.net/turing-machine"><?dsrl?><tm:head-move>right</tm:head-move></tm:output></delta><delta><label>separator</label><input><state>0</state><symbol>0</symbol></input><output><state>1</state><symbol>1</symbol><tm:head-move xmlns:tm="http://example.net/turing-machine"><?dsrl?>right</tm:head-move></output></delta><delta><label>right summand</label><input><state>1</state><symbol>1</symbol></input><tm:output xmlns:tm="http://example.net/turing-machine"><?dsrl?><tm:head-move>right</tm:head-move></tm:output></delta><delta><label>right end</label><input><state>1</state><symbol/></input><output><state>2</state><head-move>left</head-move></output></delta><delta><label>write separator</label><input><state>2</state><symbol>1</symbol></input><output><state>3</state><symbol>0</symbol><head-move>left</head-move></output></delta><delta><label>go home</label><input><state>3</state><symbol>1</symbol></input><output><head-move>left</head-move></output></delta><delta><label>final step</label><input><state>3</state><symbol/></input><output><state>4</state><tm:head-move xmlns:tm="http://example.net/turing-machine"><?dsrl?>right</tm:head-move></output></delta></transition-function></turing-machine></config>

确实,最后一个 Java 命令的输出没有 exslt 命名空间,而 Bash(使用 xsltproc)中最后一个命令的输出包含 exslt 命名空间

xmlns:exsl="http://exslt.org/common"

[1] https://github.com/mbj4668/pyang/blob/master/bin/yang2dsdl

错误 XTSE1430 表示有一个 extension-element-prefixes 属性包含尚未声明的命名空间前缀 (exsl)。

从给出的信息中不清楚 extension-element-prefixes 属性是如何生成的,但生成它的不是 Saxon,它是用户编写的 XSLT 代码,因此确保声明命名空间的责任落空了关于用户编写的代码。

Saxon 将始终确保声明元素和属性名称中使用的命名空间前缀(称为 "namespace fixup" 的过程),但它无法对文本或属性内容中使用的前缀执行此操作节点:这是用户的责任。

我没有尝试研究您 link 要访问的文件中的源代码。