2012-12-08 15 views
4

節點這裏是我有什麼,如何重新安排使用XML的Java DOM

<animation_state> 
<state>run</state> 
<animation_sequence> 
<pose duration="10" image_id="1"/> 
<pose duration="10" image_id="2"/> 
<pose duration="10" image_id="3"/> 
</animation_sequence> 

我想給用戶。然而,移動一定的圖像上下,有能力,因爲它們存儲在XML,這意味着我必須改變圖像id。如果假設用戶想要image_id = 3,要成爲序列中的第一個,或者在中間,或者取決於他的需要,我該如何操作XML?我正在使用DOM。

如果用戶想要的圖像3,是第一個,這是我的XML應如何顯示:

<animation_state> 
<state>run</state> 
<animation_sequence> 
<pose duration="10" image_id="3"/> 
<pose duration="10" image_id="1"/> 
<pose duration="10" image_id="2"/> 
</animation_sequence> 

我嘗試:

Document dom = parser.getDocument(); 
for (int i = 0; i < dom.getElementsByTagName("animation_state").getLength(); i++) 
{ 
    if (dom.getElementsByTagName("animation_state").item(i).getChildNodes().item(0).getTextContent().equalsIgnoreCase(target)) { 
     posVal = i; 
    } 
} 
NodeList list = dom.getElementsByTagName("animation_sequence").item(posVal).getChildNodes(); 

for(int b=0; b<list.getLength(); b++) 
{ 
    if(list.item(b).getAttributes().item(1).getNodeValue().equalsIgnoreCase(PoseSelectionListener.imageIDOfSelectedPose)) 
    { 
     Node toBeMoved = list.item(b); 
     dom.getElementsByTagName("animation_sequence").item(posVal).appendChild(toBeMoved); 
     System.out.println(toBeMoved.getAttributes().item(0).getNodeName()); 
    } 
} 

回答

4

使用Node.insertBefore和/或Node.appendChild 只是定位要移動的節點並找到它應該移動的位置並在其之前插入該節點。

您可能更容易將create a copy的節點移動,然後將其插入到正確的位置,然後再將其插入delete the old node

請參見下面的示例代碼:

public class SO13782330 { 
    /** Move the image whose imageId is given at first position in sequence */ 
    public static void moveImageFirst(Document doc, int imageId) throws Exception { 
     XPath xpath = XPathFactory.newInstance().newXPath(); 
     // get the image to move 
     XPathExpression poseXPath = xpath.compile("//pose[@image_id='" + imageId + "']"); 
     Node pose = (Node)poseXPath.evaluate(doc, XPathConstants.NODE); 
     // get the first image 
     XPathExpression firstPoseXPath = xpath.compile("//pose[position() = 1]"); 
     Node firstPose = (Node)firstPoseXPath.evaluate(doc, XPathConstants.NODE); 
     // copy the image to be moved 
     Node poseCopy = pose.cloneNode(true); 
     // insert it before the first one 
     Node sequence = firstPose.getParentNode(); 
     sequence.insertBefore(poseCopy, firstPose); 
     // delete the old one 
     sequence.removeChild(pose); 
    } 

    /** Print the document on stdout */ 
    public static void showDocument(Document doc) throws Exception { 
     Transformer transformer = TransformerFactory.newInstance().newTransformer(); 
     transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
     StringWriter sw = new StringWriter(); 
     transformer.transform(new DOMSource(doc), new StreamResult(sw)); 
     System.out.println(sw.getBuffer().toString()); 
    } 

    public static void main(String... args) throws Exception { 
     DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
     Document doc = db.parse(new InputSource(new StringReader("<animation_state>\n" + 
       "<state>run</state>\n" + 
       "<animation_sequence>\n" + 
       "<pose duration=\"10\" image_id=\"1\"/>\n" + 
       "<pose duration=\"10\" image_id=\"2\"/>\n" + 
       "<pose duration=\"10\" image_id=\"3\"/>\n" + 
       "</animation_sequence>\n" + 
       "</animation_state>"))); 
     moveImageFirst(doc, 3); 
     showDocument(doc); 
    } 
} 

它將移動具有image_id屬性等於3第一個前pose元件。

+0

這不正是我現在正在做什麼?我找到了它,然後我追加它。請幫我Alex – user1888502

+0

查看樣本的編輯。 – Alex

+0

感謝您的建議,XML API有許多不同的調用,試驗和錯誤需要很長時間。複製節點變得重要。 –

3

你不需要複製/克隆節點。

只需做以下操作:

public void addNodeAfter(Node newNode, Node refChild) { 
    Node parent = refChild.getParent(); 
    parent.insertBefore(newNode, refChild); 
    refChild = parent.remove(refChild); 
    parent.insertBefore(refChild, newNode); 
} 

可能比克隆一個更好的解決方案。

+0

歡迎來到堆棧溢出!僅有代碼的答案不是很有幫助。請編輯您的答案,以解釋爲什麼您的代碼可以解決原始問題。 –