javaxmljdom-2

Move XML child element up without changing text flow


I have xml files which look like:

<a>
  <s> blah blah </s>
  <s> bleep  
      <t> something different </t> 
      bloop</s>
  <s> bleh bleh </s>
</a>

and would like to move the <t> elements up one level, without changing the text flow : in other words I want it to look like

<a>
  <s> blah blah </s>
  <s> bleep </s> 
  <t> something different </t> 
  <s> bloop</s>
  <s> bleh bleh </s>
</a>

I am using java with jdom2, and there must surely be a straightforward method for this, but I can't find it. Any elegant ideas? Thanks!


Solution

  • Ok, here is how I ended up doing it inelegantly by hand, for posterity:

    List<Element> lstChildren = new ArrayList<Element>(eltA.getChildren());
    for (Element eltS : lstChildren) {
    
        //find s
        if (eltS.getName().contentEquals("s")) {
    
            int indexS = eltA.indexOf(eltS);
            List<Element> lstSub = new ArrayList<Element>(eltS.getChildren());
            for (Element eltT : lstSub) {
    
                //find t
                if (eltT.getName().contentEquals("t")) {
    
                    //split the text at the child:
                    int index = eltS.indexOf(eltT);
    
                    if (index < eltS.getText().length()) {
                        Element elt1 = eltS.clone();
                        Element elt2 = eltS.clone();
    
                        for (int i = index; i < eltS.getContentSize(); i++) {
                            elt1.removeContent(index);                                                        
                        }
                        for (int i = 0; i <= index; i++) {
                            elt2.removeContent(0);                                                        
                        }
    
                        eltA.removeContent(indexS);
                        eltA.addContent(indexS, elt1);
                        eltA.addContent(indexS + 1, elt2);
                    }
    
                    //move it up one level
                    eltT.detach();
                    eltA.addContent(indexS + 1, eltT);
                }
            }
        }
    }