adding namespace and namespace prefix using dom4j

2019-08-01 07:03发布

i am updating one xml using dom4j as below.

    SAXReader reader = new SAXReader();
document = reader.read( xmlFileName );

but it removes all namespaces from the elements so wanna add manually but it does not work when i tried the following code.

    Element e1 = root.addElement("jmsProducer");   
    e1.addNamespace("AEService", "http://www.tibco.com/xmlns/aemeta/services/2002");

my xml looks like

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

which sud look like

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

any help is highly appriciated. banging on this for two days tried using documentfactory method still no use.

5条回答
Evening l夕情丶
2楼-- · 2019-08-01 07:12

I realize that this is an old thread, and dom4j may not have had adequate namespace capabilities at the time the answers were written, but it looks like dom4j is now able to accomplish this quite easily with the version I am using (1.6.1). I came here looking for help on how to build a namespace aware XML with dom4j, posting my Java code (to build the XML snippet in the original post) in case it helps someone.

Here is the Java code to build it.

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);

produces this output:

<?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>

Hope this helps.

查看更多
Fickle 薄情
3楼-- · 2019-08-01 07:24

I found that in order for the namespace to be correctly set it needed to be recursively set on the entire hierarchy of nodes.

these two methods do the trick:

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

then I am able to add the namespace like so:

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

Hope this helps

查看更多
女痞
4楼-- · 2019-08-01 07:26

I suggest you dump dom4j and use JAXB or StAX. If you can't do that then try the below (I didn't verify this so post follow up questions as comments)

Namespace ns = new Namespace("AEService","http://www.tibco.com/xmlns/aemeta/services/2002")
document.add(ns);
查看更多
祖国的老花朵
5楼-- · 2019-08-01 07:27

I am able to add a namespace at the child element instead of the root element with the below steps:

  1. find the Node using xpath from created document.

  2. create name space prefix name and value.

  3. Add as element into node as below:

    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));
    
查看更多
我只想做你的唯一
6楼-- · 2019-08-01 07:27

Using the library dom4j:2.1.1

After initializing the document:

SAXReader reader = new SAXReader();
reader.getDocumentFactory().setXPathNamespaceURIs(ImmutableMap.of("x", "DAV:"));
Document doc = reader.read(new StringReader(xmlContent));
doc.getRootElement().selectNodes("//x:response")

I can prefix with the namespace x: the XPath expression.

Note: an empty namespace is not allowed. You need to specify a prefix.

查看更多
登录 后发表回答