如何使用非命名空间感知解析器在Java中进行XSL转换?

时间:2015-06-08 11:18:09

标签: java xslt sax tag-soup

我使用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,一切都很顺利。然而,这不是我想要的,我希望这可以开箱即用&#34;开箱即用#34;。我究竟做错了什么?任何意见都将不胜感激!

1 个答案:

答案 0 :(得分:0)

  

我希望这可以“开箱即用”。我做错了什么?

您所做错的是采用一种技术(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实现)中,您唯一的选择是使用前缀。