java - Java 中极慢的 XSLT 转换

标签 java xml xslt

我尝试使用 XSLT 转换 XML 文档。作为输入,我有 www.wordpress.org XHTML 源代码,而 XSLT 是检索站点标题的虚拟示例(实际上它什么也做不了——它不会改变任何东西)。

我使用的每个 API 或库,转换大约需要 2 分钟!如果您查看 wordpress.org 源代码,您会注意到它只有 183 行代码。当我用谷歌搜索时,这可能是由于 DOM 树构建。无论 XSLT 多么简单,它总是 2 分钟 - 所以它证实了它与 DOM 构建相关的想法,但无论如何我认为它不应该花费 2 分钟。

这是一个示例代码(没什么特别的):

  TransformerFactory tFactory = TransformerFactory.newInstance();
   Transformer transformer = null;

   try {
       transformer = tFactory.newTransformer(
           new StreamSource("/home/pd/XSLT/transf.xslt"));

   } catch (TransformerConfigurationException e) {
       e.printStackTrace();
   }

   ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

   System.out.println("START");
   try {
       transformer.transform(new SAXSource(new InputSource(
           new FileInputStream("/home/pd/XSLT/wordpress.xml"))),
           new StreamResult(outputStream));
   } catch (TransformerException e) {       
       e.printStackTrace();
   } catch (IOException e) {
       e.printStackTrace();
   }
   System.out.println("STOP");

   System.out.println(new String(outputStream.toByteArray()));

在 START 和 STOP 之间,java 会“暂停”2 分钟。如果我查看处理器或内存使用情况,没有任何增加。看起来 JVM 真的停止了......

您有转换超过 50(这是随机数 ;))行的 XML 的经验吗?正如我所阅读的那样,XSLT 总是需要构建 DOM 树才能完成它的工作。快速转型对我来说至关重要。

提前致谢, 彼得

最佳答案

示例 HTML 文件是否使用命名空间?如果是这样,您的 XML 解析器可能会尝试从命名空间 URI 中检索内容(可能是模式)。如果每次运行恰好需要两分钟,这很可能发生——很可能是一个或多个 TCP 超时。

您可以通过计算实例化您的 InputSource 对象(实际解析 WordPress XML 的地方)所需的时间来验证这一点,因为这可能是导致延迟的行。查看您发布的示例文件后,它确实包含一个声明的命名空间 (xmlns="http://www.w3.org/1999/xhtml")。

要解决此问题,您可以实现自己的 EntityResolver这实际上禁用了基于 URL 的解析。您可能需要使用 DOM——参见 DocumentBuildersetEntityResolver方法。

这是一个使用 DOM 并禁用分辨率的示例(注意——这是未经测试的):

try {
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbFactory.newDocumentBuilder();
    db.setEntityResolver(new EntityResolver() {

        @Override
        public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
            return null; // Never resolve any IDs
        }
    });

    System.out.println("BUILDING DOM");

    Document doc = db.parse(new FileInputStream("/home/pd/XSLT/wordpress.xml"));

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

    TransformerFactory tFactory = TransformerFactory.newInstance();
    Transformer transformer = tFactory.newTransformer(
        new StreamSource("/home/pd/XSLT/transf.xslt"));

    System.out.println("RUNNING TRANSFORM");

    transformer.transform(
            new DOMSource(doc.getDocumentElement()),
            new StreamResult(outputStream));

    System.out.println("TRANSFORMED CONTENTS BELOW");
    System.out.println(outputStream.toString());
} catch (Exception e) {
    e.printStackTrace();
}

如果您想使用 SAX,则必须使用 SAXSourceXMLReader它使用您的自定义解析器。

关于java - Java 中极慢的 XSLT 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4799136/

相关文章:

java - Sqlite 语法错误

java - JNLP 下载期间出现 FileNotFoundException

android - ProgressBar 间隙

android - 自定义小部件 : Error inflating class

xml - Xsl:如何确定节点或其后代是否包含文本

java - 在SQL数据库(例如H2)中插入和获取java.time.LocalDate对象

sql - 如何在 SQL Server 2008 R2 中根据参数名称检索 xml 数据类型中的属性值?

c# - JIT 编译器遇到内部限制。 VS2008

xslt - XSL计数连续节点

java - 如何通过maven连接吗啡注释类?