JDOM XPath 获取没有命名空间的内部元素
JDOM XPath Getting Inner Element without Namespace
我有一个 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 的期望,我认为它是 "right"。 JDOM 的 XMLOutputter 还输出结构良好且内部一致的 XML 和 XML 片段。
更改内部内存模型的行为不是 JDOM 的选项,但自定义 XMLOutputter 以更改其行为相对容易。 XMLOutputter 的结构是将 "engine" 作为构造函数参数提供:XMLOutputter(XMLOutputProcessor)
. In addition, JDOM supplies an easy-to-customize default XMLOutputProcessor
called AbstractXMLOutputProcessor
.
您可以通过执行以下操作获得所需的行为:
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>
我有一个 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 的期望,我认为它是 "right"。 JDOM 的 XMLOutputter 还输出结构良好且内部一致的 XML 和 XML 片段。
更改内部内存模型的行为不是 JDOM 的选项,但自定义 XMLOutputter 以更改其行为相对容易。 XMLOutputter 的结构是将 "engine" 作为构造函数参数提供:XMLOutputter(XMLOutputProcessor)
. In addition, JDOM supplies an easy-to-customize default XMLOutputProcessor
called AbstractXMLOutputProcessor
.
您可以通过执行以下操作获得所需的行为:
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>