Java 使用dom4j添加名称空间和名称空间前缀
我正在使用dom4j更新一个xml,如下所示Java 使用dom4j添加名称空间和名称空间前缀,java,xml-parsing,xml-namespaces,dom4j,Java,Xml Parsing,Xml Namespaces,Dom4j,我正在使用dom4j更新一个xml,如下所示 SAXReader reader = new SAXReader(); document = reader.read( xmlFileName ); 但是它从元素中删除了所有名称空间,所以我想手动添加,但是当我尝试下面的代码时,它不起作用 Element e1 = root.addElement("jmsProducer"); e1.addNamespace("AEService", "http://www.tibco
SAXReader reader = new SAXReader();
document = reader.read( xmlFileName );
但是它从元素中删除了所有名称空间,所以我想手动添加,但是当我尝试下面的代码时,它不起作用
Element e1 = root.addElement("jmsProducer");
e1.addNamespace("AEService", "http://www.tibco.com/xmlns/aemeta/services/2002");
我的xml看起来像
<AEService:jmsProducer objectType="endpoint.JMSPublisher" name="Pub1EndPoint">
<AEService:wireFormat>aeXml</AEService:wireFormat>
aeXml
哪个看起来像
<AEService:jmsProducer xmlns:AEService="http://www.tibco.com/xmlns/aemeta/services /2002" objectType="endpoint.JMSPublisher" name="Pub1EndPoint">
<AEService:wireFormat>aeXml</AEService:wireFormat>
aeXml
任何帮助都是非常感谢的。连续两天尝试使用documentfactory方法仍然没有用 我建议您转储dom4j并使用JAXB或StAX。如果你不能做到这一点,那么尝试下面的方法(我没有验证这一点,所以将后续问题作为评论发布)
我建议您转储dom4j并使用JAXB或StAX。如果你不能做到这一点,那么尝试下面的方法(我没有验证这一点,所以将后续问题作为评论发布)
我发现为了正确设置名称空间,需要在整个节点层次结构上递归设置名称空间 这两种方法起到了作用:
/**
* Recursively sets the namespace of the element and all its children.
*/
private void setNamespaces( Element elem, Namespace ns ) {
setNamespace( elem, ns );
setNamespaces( elem.content(), ns );
}
/**
* Recursively sets the namespace of the List and all children if the
* current namespace is match
*/
private void setNamespaces( List l, Namespace ns ) {
Node n = null;
for ( int i = 0; i < l.size(); i++ ) {
n = ( Node ) l.get( i );
if ( n.getNodeType() == Node.ATTRIBUTE_NODE ) {
(( Attribute ) n).setNamespace( ns );
}
if ( n.getNodeType() == Node.ELEMENT_NODE ) {
setNamespaces( ( Element ) n, ns );
}
}
}
希望这有帮助我发现为了正确设置名称空间,需要在整个节点层次结构上递归设置名称空间 这两种方法起到了作用:
/**
* Recursively sets the namespace of the element and all its children.
*/
private void setNamespaces( Element elem, Namespace ns ) {
setNamespace( elem, ns );
setNamespaces( elem.content(), ns );
}
/**
* Recursively sets the namespace of the List and all children if the
* current namespace is match
*/
private void setNamespaces( List l, Namespace ns ) {
Node n = null;
for ( int i = 0; i < l.size(); i++ ) {
n = ( Node ) l.get( i );
if ( n.getNodeType() == Node.ATTRIBUTE_NODE ) {
(( Attribute ) n).setNamespace( ns );
}
if ( n.getNodeType() == Node.ELEMENT_NODE ) {
setNamespaces( ( Element ) n, ns );
}
}
}
希望这有帮助我意识到这是一个旧线程,在编写答案时dom4j可能没有足够的名称空间功能,但看起来dom4j现在可以很容易地用我正在使用的版本(1.6.1)实现这一点。我来这里寻求帮助,了解如何使用dom4j构建支持名称空间的XML,并发布我的Java代码(在原始文章中构建XML片段),以防它对某人有所帮助 下面是构建它的Java代码
Document xmldoc = DocumentHelper.createDocument();
Namespace aeServiceNs = new Namespace("AEService",
"http://www.tibco.com/xmlns/aemeta/services/2002");
Element root = xmldoc.addElement(new QName("jmsProducer", aeServiceNs))
.addAttribute("objectType", "endpoint.JMSPublisher")
.addAttribute("name", "Pub1EndPoint");
Element wireformat = root.addElement(new QName("wireFormat", aeServiceNs))
.setText("aeXml");
OutputFormat outputFormat = OutputFormat.createPrettyPrint();
XMLWriter xmlwriter = new XMLWriter(System.out, outputFormat);
xmlwriter.write(xmldoc);
生成此输出:
<?xml version="1.0" encoding="UTF-8"?>
<AEService:jmsProducer
xmlns:AEService="http://www.tibco.com/xmlns/aemeta/services/2002"
objectType="endpoint.JMSPublisher" name="Pub1EndPoint">
<AEService:wireFormat>aeXml</AEService:wireFormat>
</AEService:jmsProducer>
aeXml
希望这能有所帮助。我意识到这是一个旧线程,在编写答案时,dom4j可能没有足够的命名空间功能,但看起来dom4j现在可以很容易地用我正在使用的版本(1.6.1)实现这一点。我来这里寻求帮助,了解如何使用dom4j构建支持名称空间的XML,并发布我的Java代码(在原始文章中构建XML片段),以防它对某人有所帮助 下面是构建它的Java代码
Document xmldoc = DocumentHelper.createDocument();
Namespace aeServiceNs = new Namespace("AEService",
"http://www.tibco.com/xmlns/aemeta/services/2002");
Element root = xmldoc.addElement(new QName("jmsProducer", aeServiceNs))
.addAttribute("objectType", "endpoint.JMSPublisher")
.addAttribute("name", "Pub1EndPoint");
Element wireformat = root.addElement(new QName("wireFormat", aeServiceNs))
.setText("aeXml");
OutputFormat outputFormat = OutputFormat.createPrettyPrint();
XMLWriter xmlwriter = new XMLWriter(System.out, outputFormat);
xmlwriter.write(xmldoc);
生成此输出:
<?xml version="1.0" encoding="UTF-8"?>
<AEService:jmsProducer
xmlns:AEService="http://www.tibco.com/xmlns/aemeta/services/2002"
objectType="endpoint.JMSPublisher" name="Pub1EndPoint">
<AEService:wireFormat>aeXml</AEService:wireFormat>
</AEService:jmsProducer>
aeXml
希望这有帮助。我可以通过以下步骤在子元素而不是根元素添加名称空间:
Document document = DocumentHelper.createDocument();
Element documentRoot = null;
Element created = null;
Node parentNode = null;
documentRoot = DocumentHelper.createElement();
parentNode = documentRoot.selectSingleNode("parentXPath");
Namespace ns = new Namespace("name","value");
created = ((Element) parentNode).addElement(new QName("elementName",ns1));
我可以通过以下步骤在子元素而不是根元素添加名称空间:
Document document = DocumentHelper.createDocument();
Element documentRoot = null;
Element created = null;
Node parentNode = null;
documentRoot = DocumentHelper.createElement();
parentNode = documentRoot.selectSingleNode("parentXPath");
Namespace ns = new Namespace("name","value");
created = ((Element) parentNode).addElement(new QName("elementName",ns1));
SAXReader reader = new SAXReader();
reader.getDocumentFactory().setXPathNamespaceURIs(ImmutableMap.of("x", "DAV:"));
Document doc = reader.read(new StringReader(xmlContent));
doc.getRootElement().selectNodes("//x:response")
我可以使用名称空间x:
作为XPath表达式的前缀
注意:不允许使用空命名空间。您需要使用库dom4j:2.1.1指定前缀。
初始化文档后:
SAXReader reader = new SAXReader();
reader.getDocumentFactory().setXPathNamespaceURIs(ImmutableMap.of("x", "DAV:"));
Document doc = reader.read(new StringReader(xmlContent));
doc.getRootElement().selectNodes("//x:response")
我可以使用名称空间x:
作为XPath表达式的前缀
注意:不允许使用空命名空间。您需要指定前缀。我无法添加到文档本身,但当添加到元素时它没有添加,但当我尝试使用名称空间ns=new名称空间(“:AEService“,”)时,xml将显示为“/2002”objectType=“endpoint.JMSPublisher”name=“Pub1EndPoint”>“如果能以某种方式删除额外的冒号,我的工作就完成了。由于您的代码,额外的列将出现。”。将名称空间ns=new Namespace(“:AEService”,“tibco.com/xmlns/aemeta/services/2002”)更改为名称空间ns=new Namespace(“AEService”,“tibco.com/xmlns/aemeta/services/2002”),在AEService之前有一个冒号,因此创建了一个额外的冒号。我知道我添加了额外的冒号,因为当我不添加名称空间时,我会创建类似于名称空间ns=new Namespace(“AEService”、“tibco.com/xmlns/aemeta/services/2002”)它根本没有添加任何namspace:(…有些棘手的事情…我无法添加到文档本身,但当添加到元素时它没有添加,但当我尝试使用名称空间ns=new Namespace(“:AEService“,”)时,xml显示为“/2002”objectType=“endpoint.jmsublisher”name=”Pub1EndPoint“>”如果可以以某种方式删除额外的冒号,我的工作就完成了。由于您的代码,额外的列将出现。将名称空间ns=新名称空间(“:AEService”,“tibco.com/xmlns/aemeta/services/2002”)更改为名称空间ns=新名称空间(“AEService”,“tibco.com/xmlns/aemeta/services/2002”)您在AEService之前有一个冒号,因此创建了一个额外的冒号。我知道我添加了额外的冒号,因为当我不添加时,我创建了类似名称空间ns=新名称空间(“AEService”,“tibco.com/xmlns/aemeta/services/2002”),它根本不添加任何名称空间:(…有些什么棘手的…你声明了变量
ns
,但没有使用它。你也使用变量ns1
,但你没有声明它。我怀疑它甚至会编译为一个片段。你声明了变量ns
,但没有使用它。你也使用变量ns1
,但你没有声明它。我怀疑它甚至会编译为一个片段。