2

我正在使用 dom4j 更新一个 xml,如下所示。

    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>

哪个 sud 看起来像

    <AEService:jmsProducer xmlns:AEService="http://www.tibco.com/xmlns/aemeta/services   /2002" objectType="endpoint.JMSPublisher" name="Pub1EndPoint">
    <AEService:wireFormat>aeXml</AEService:wireFormat>

任何帮助都是高度赞赏的。敲了两天尝试使用documentfactory方法仍然没有用。

4

5 回答 5

3

我意识到这是一个旧线程,并且在编写答案时 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>

希望这可以帮助。

于 2015-07-17T17:52:24.533 回答
1

我建议你转储 dom4j 并使用 JAXB 或 StAX。如果您不能这样做,请尝试以下操作(我没有对此进行验证,因此将后续问题作为评论发布)

Namespace ns = new Namespace("AEService","http://www.tibco.com/xmlns/aemeta/services/2002")
document.add(ns);
于 2012-11-02T09:22:45.733 回答
0

我发现为了正确设置命名空间,需要在整个节点层次结构上递归设置。

这两种方法可以解决问题:

   /**
    * 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 );
         }
      }
   }

然后我可以像这样添加命名空间:

setNamespaces( ( Element ) xml.selectSingleNode( "/root/settings" ),
                  new Namespace( "", "http://www.penvision.se/printprocessor" ) );

希望这可以帮助

于 2012-11-27T21:26:54.777 回答
0

我可以通过以下步骤在子元素而不是根元素处添加命名空间:

  1. 使用创建的文档中的 xpath 找到节点。

  2. 创建名称空间前缀名称和值。

  3. 将元素添加到节点中,如下所示:

    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));
    
于 2017-08-16T12:15:57.037 回答
0

使用库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 表达式的名称空间前加上前缀。

注意:不允许使用空的命名空间。您需要指定一个前缀。

于 2019-02-03T15:56:23.147 回答