2012-12-08 4 views
4

을 사용하여 노드 순서를 변경하는 방법 여기, 내가 가진 무엇XML 자바 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); 
    } 
} 

그것은 pose 요소가 image_id 속성이 첫 번째 전에 3 같음 가진 이동합니다 :

아래의 샘플 코드를 참조하십시오.

+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

스택 오버플로에 오신 것을 환영합니다! 코드 전용 답변은별로 도움이되지 않습니다. 코드가 원래의 문제를 해결하는 이유를 설명하기 위해 답을 편집하십시오. –