2010-11-15 73 views
4

這個問題的DOM的順序屬性已計算器之前問:爲了元素

setting order of attributes

這真的不可能?使用insertBefore我想排序一個元素的屬性序列。具體而言,在下面的示例中,如何更改屬性的順序?從節點使用setAttribute會更容易嗎?無論哪種情況,順序似乎都是自動發生的,儘管insertBefore當然意味着可以指定順序。

代碼:

package xml; 

import java.io.FileWriter; 
import java.io.IOException; 
import java.io.StringWriter; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.transform.TransformerConfigurationException; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.transform.OutputKeys; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerFactory; 
import org.w3c.dom.Attr; 
import org.w3c.dom.Comment; 
import org.w3c.dom.Document; 
import org.w3c.dom.Element; 

public class Main { 

    private static final Logger logger = Logger.getLogger(Main.class.getName()); 

    /** 
    * catches errors 
    */ 
    public Main() { 
     try { 
      createDoc(); 
     } catch (ParserConfigurationException ex) { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (TransformerConfigurationException ex) { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (TransformerException ex) { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (IOException ex) { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 


    private void createDoc() 
      throws ParserConfigurationException, TransformerConfigurationException, TransformerException, IOException { 

     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     dbf.setNamespaceAware(true); 
     dbf.setIgnoringComments(false); 
     DocumentBuilder db = dbf.newDocumentBuilder(); 
     Document doc = db.newDocument(); 
     doc.setXmlStandalone(true); 

     Comment comment = doc.createComment(" nodes "); 
     doc.appendChild(comment); 

     Element root = doc.createElement("foo"); 
     root.setAttribute("Version", "1.0"); 
     doc.appendChild(root); 

     Element bar = doc.createElement("bar"); 

     Element baz = doc.createElement("baz"); 

     Element child1 = doc.createElementNS("foo", "bar"); 
     child1.setPrefix("prefix1"); 
     Attr attr1 = doc.createAttribute("attr1"); 
     attr1.setValue("val1"); 

     Element child2 = doc.createElementNS("foo", "bar"); 
     child2.setPrefix("prefix2"); 
     Attr attr2 = doc.createAttribute("attr2"); 
     attr2.setValue("val2"); 

     baz.setAttributeNode(attr2); 
     baz.setAttributeNode(attr1); 

     root.appendChild(bar); 
     bar.appendChild(baz); 
     writeToFile(doc); 
    } 

    private void writeToFile(Document doc) 
      throws TransformerConfigurationException, TransformerException, IOException { 
     TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
     transformerFactory.setAttribute("indent-number", new Integer(2)); 
     Transformer transformer = transformerFactory.newTransformer(); 
     transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); 
     transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
     transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 
     transformer.setOutputProperty(OutputKeys.VERSION, "1.0"); 
     StringWriter sw = new StringWriter(); 
     StreamResult result = new StreamResult(sw); 
     DOMSource source = new DOMSource(doc); 
     transformer.transform(source, result); 
     logger.log(Level.INFO, "\n{0}", sw.toString()); 
     result = new StreamResult(new FileWriter("test.xml")); 
     transformer.transform(source, result); 
    } 

    public static void main(String args[]) { 
     Main main = new Main(); 
    } 
} 
+0

這是可能的,但只有與vtd-xml ...由於其非提取性質 – 2016-05-23 22:45:01

回答

4

XML元素的屬性的順序不是XML information set的一部分,並且因此實現(包括DOM的,解析器和unparsers)不一定要保存它。

實際上,這意味着它對於是否可以通過DOM API控制屬性的順序(例如,使用insertBefore)是特定於實現的,並且它是實現特定的,是否跨轉換保留排序。

我的建議是更改您的應用程序,使其不依賴於XML屬性排序。

+0

我無法弄清楚如何使用插入前:( – Thufir 2010-11-15 06:11:18

+0

這可能意味着它根本不會工作您正在使用的DOM實現。 – 2010-11-15 11:23:33

2

它在底層XML中不受支持。也許你可以利用圖書館的特定實現來獲得你想要的訂單,但是不能保證它會永遠那樣工作。

想想這樣,一個屬性是一個元素的描述性項目。如果你身材瘦高,那麼你的屬性確實沒有自然排序。高個子不要像高個子一樣要瘦,要麼瘦得高。同樣,一輛熱的,快速的紅色汽車與其他汽車並沒有區別,它們是熱的,快速的,紅色的,而不是快速的,紅色的和熱的。

從實際的角度來看,您所希望的最好的方法是從節點中刪除所有屬性,並找出底層代碼的工作方式。按照正確的順序添加所有屬性,可以根據特定的情況獲取您希望的訂單,以獲取特定的庫版本。不理想,但如果這對你很重要,任何解決方案總比沒有解決方案好。