使用dom4j添加名称空间和名称空间前缀

时间:2012-11-02 08:48:10

标签: 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.com/xmlns/aemeta/services/2002");

我的xml看起来像

    <AEService:jmsProducer objectType="endpoint.JMSPublisher" name="Pub1EndPoint">  
    <AEService:wireFormat>aeXml</AEService:wireFormat>

哪个看起来像

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

任何帮助都非常有用。在这两天试过使用documentfactory方法仍然没有用。

5 个答案:

答案 0 :(得分:2)

我意识到这是一个旧线程,并且在编写答案时dom4j可能没有足够的命名空间功能,但看起来dom4j现在能够使用我正在使用的版本轻松完成此任务(1.6 0.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>

希望这有帮助。

答案 1 :(得分:1)

我建议您转储dom4j并使用JAXB或StAX。如果你不能这样做,那么试试下面(我没有验证这个,所以发布后续问题作为评论)

Namespace ns = new Namespace("AEService","http://www.tibco.com/xmlns/aemeta/services/2002")
document.add(ns);

答案 2 :(得分: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" ) );

希望这有帮助

答案 3 :(得分:0)

我可以使用以下步骤在子元素而不是根元素中添加命名空间:

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

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

  3. 将as as element添加到节点中,如下所示:

    {
        xtype: 'box',
        autoEl: {
            'data-qtip': "Tooltip text"
        }
    }
    

答案 4 :(得分: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")

我可以在XPath表达式的名称空间x:前面加上前缀。

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