如何使用不支持名称空间的解析器在 Java 中进行 XSL 转换?

How to do a XSL transform in Java using a not namespace aware parser?

我将 tagsoup 用作 (SAX) XMLREader 并将名称空间功能设置为 false。此解析器用于将 Transformer 作为 SAX 源提供。完整代码:

    final TransformerFactory factory = TransformerFactory.newInstance();
    final Transformer t = factory.newTransformer(new StreamSource(
        getClass().getResourceAsStream("/identity.xsl")));

    final XMLReader p = new Parser(); // the tagsoup parser
    p.setFeature("http://xml.org/sax/features/namespaces", false);

    // getHtml() returns HTML as InputStream
    final Source source = new SAXSource(p, new InputSource(getHtml())); 

    t.transform(source, new StreamResult(System.out));

结果如下:

< xmlns:html="http://www.w3.org/1999/xhtml">
<>
<>
<>
<>
< height="17" valign="top">

问题是标签名称为空。 XMLReader(tagsoup 解析器)确实在 SAX 方法 ContentHandler#startElementContentHandler#endElement 中报告了一个空的 namespaceURI 和一个空的本地名称。对于不支持命名空间的解析器,这是允许的(参见 Javadoc)。

如果我添加一个 XMLFilter 将 qName 的值复制到 localName,一切都会正常进行。然而,这不是我想要的,我希望它能工作 "out of the box"。我究竟做错了什么?如有任何意见,我们将不胜感激!

I expect this works "out of the box". What am i doing wrong?

您做错的是采用定义为在格式良好的名称空间上运行的技术 (XSLT) XML 并试图将其应用于不打算使用的数据。如果您想使用 XSLT,那么您 必须 启用命名空间,在您的样式表中为 http://www.w3.org/1999/xhtml 命名空间声明一个前缀,并在您的 XPath 表达式中一致地使用该前缀。

如果您的转换器理解 XSLT 2.0(例如 Saxon 9),那么您可以将 xpath-default-namespace="http://www.w3.org/1999/xhtml" 放在 xsl:stylesheet 元素上,而不是在 XPath 表达式中声明前缀和前缀元素名称使其将无前缀的元素名称视为对该名称空间的引用。但在 XSLT 1.0(默认内置 Java Transformer 实现)中,您唯一的选择是使用前缀。