首页 > 解决方案 > 将 XML 从 DOM 解析器重构为 SAX 解析器

问题描述

遗留代码使用 DOM 解析器来解析一个非常大的 XML 文件。

工作流程: 1. 从文档中清理命名空间。document.accept(new NameSpaceCleaner()); 这是命名空间清洁器类。 final class NameSpaceCleaner extends VisitorSupport { @Override public void visit(Document document) {
((DefaultElement) document.getRootElement()).setNamespace(Namespace.NO_NAMESPACE); document.getRootElement().additionalNamespaces().clear(); }

@Override
public void visit(Attribute node)
{
     if (node.toString().contains("xmlns") || node.toString().contains("xsi:")) {
        node.detach();
    }
}

@Override
public void visit(Element node)
{
    if (node instanceof DefaultElement) {
        ((DefaultElement) node).setNamespace(Namespace.NO_NAMESPACE);
    }
}

不知道如何使用 SAX 解析器清理命名空间。

标签: xmldomnamespacessax

解决方案


我不能 100% 确定您的代码在做什么: DefaultElement 类似乎是 Xerces 内部的东西,我不知道您的测试“node instanceof DefaultElement”何时成功。我假设它正在测试节点是否在默认命名空间中,并且您正在尝试将默认命名空间中的所有节点移动到没有命名空间中。

我不会为您提供 SAX 解决方案,因为我没有时间或精力来编写这样的低级代码,但如果您想使用 XSLT 3.0 流式处理,那么它是:

<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <xsl:mode streamable="yes"/>

  <xsl:template match="*[namespace-uri()='']">
    <xsl:element name="{local-name()}">
      <xsl:copy-of select="@* except @xsi:*"/>
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="*[namespace-uri()!='']">
    <xsl:copy copy-namespaces="no">
      <xsl:copy-of select="@* except @xsi:*"/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

</xsl:transform>

推荐阅读