当前位置: 代码迷 >> java >> 没有命名空间的JDOM XPath获取内部元素
  详细解决方案

没有命名空间的JDOM XPath获取内部元素

热度:72   发布时间:2023-07-26 13:50:38.0

我有这样的xml:

<root
    xmlns:gl-bus="http://www.xbrl.org/int/gl/bus/2006-10-25"
    xmlns:gl-cor="http://www.xbrl.org/int/gl/cor/2006-10-25" >
    <gl-cor:entityInformation>
        <gl-bus:accountantInformation>
            ...............
        </gl-bus:accountantInformation>
    </gl-cor:entityInformation>
</root>

我只想从根及其子元素中提取元素“ gl-cor:entityInformation”。 但是,我不希望它带有名称空间声明。

代码是这样的:

XPathExpression<Element> xpath = XPathFactory.instance().compile("gl-cor:entityInformation", Filters.element(), null, NAMESPACES);
Element innerElement = xpath.evaluateFirst(xmlDoc.getRootElement());

问题在于内部元素现在保留名称空间声明。 样本输出:

<gl-cor:entityInformation xmlns:gl-cor="http://www.xbrl.org/int/gl/cor/2006-10-25">
    <gl-bus:accountantInformation xmlns:gl-bus="http://www.xbrl.org/int/gl/bus/2006-10-25">
    </gl-bus:accountantInformation>
</gl-cor:entityInformation>

这就是我如何以字符串形式获取xml:

public static String toString(Element element) {
    Format format = Format.getPrettyFormat();
    format.setTextMode(Format.TextMode.NORMALIZE);
    format.setEncoding("UTF-8");

    XMLOutputter xmlOut = new XMLOutputter(); 
    xmlOut.setFormat(format);
    return xmlOut.outputString(element);
}

如您所见,名称空间声明被传递到内部元素中。 有没有办法在不丢失前缀的情况下摆脱这些声明?

我想要这个,因为稍后我将这些内部元素合并到另一个父元素中,并且该父元素已经具有那些名称空间声明。

JDOM通过设计坚持认为,XML的内存模型始终都具有良好的结构。 您所看到的行为正是我对JDOM的期望,我认为它是“正确的”。 JDOM的XMLOutputter还可以输出结构良好且内部一致的XML和XML片段。

更改内部内存模型的行为不是JDOM的选择,但是自定义XMLOutputter以更改其行为相对容易。 XMLOutputter被构造为具有作为构造函数参数提供的“引擎”: 。 另外,JDOM提供了一个易于定制的默认XMLOutputProcessor称为 。

您可以通过执行以下操作获得所需的行为:

private static final XMLOutputProcessor noNamespaces = new AbstractXMLOutputProcessor() {

    @Override
    protected void printNamespace(final Writer out, final FormatStack fstack, 
        final Namespace ns)  throws IOException {
        // do nothing with printing Namespaces....
    }

};

现在,当您创建XMLOutputter来打印XML元素片段时,可以执行以下操作:

public static String toString(Element element) {
    Format format = Format.getPrettyFormat();
    format.setTextMode(Format.TextMode.NORMALIZE);
    format.setEncoding("UTF-8");

    XMLOutputter xmlOut = new XMLOutputter(noNamespaces); 
    xmlOut.setFormat(format);
    return xmlOut.outputString(element);
}

这是使用您的输入XML的完整程序:

import java.io.IOException;
import java.io.Writer;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.Namespace;
import org.jdom2.filter.Filters;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import org.jdom2.output.support.AbstractXMLOutputProcessor;
import org.jdom2.output.support.FormatStack;
import org.jdom2.output.support.XMLOutputProcessor;
import org.jdom2.xpath.XPathExpression;
import org.jdom2.xpath.XPathFactory;


public class JDOMEray {

    public static void main(String[] args) throws JDOMException, IOException {
        Document eray = new SAXBuilder().build("eray.xml");
        Namespace[] NAMESPACES = {Namespace.getNamespace("gl-cor", "http://www.xbrl.org/int/gl/cor/2006-10-25")};
        XPathExpression<Element> xpath = XPathFactory.instance().compile("gl-cor:entityInformation", Filters.element(), null, NAMESPACES);
        Element innerElement = xpath.evaluateFirst(eray.getRootElement());

        System.out.println(toString(innerElement));
    }

    private static final XMLOutputProcessor noNamespaces = new AbstractXMLOutputProcessor() {

        @Override
        protected void printNamespace(final Writer out, final FormatStack fstack, 
            final Namespace ns)  throws IOException {
            // do nothing with printing Namespaces....
        }

    };

    public static String toString(Element element) {
        Format format = Format.getPrettyFormat();
        format.setTextMode(Format.TextMode.NORMALIZE);
        format.setEncoding("UTF-8");

        XMLOutputter xmlOut = new XMLOutputter(noNamespaces); 
        xmlOut.setFormat(format);
        return xmlOut.outputString(element);
    }


}

对我来说,上面的程序输出:

<gl-cor:entityInformation>
  <gl-bus:accountantInformation>...............</gl-bus:accountantInformation>
</gl-cor:entityInformation>