Some Text Here Some Text Here ...">

Dom4j detach node, Jython

I am using Dom4j to detach node like below:

<div name="divName">
    Some Text Here
    <span>Some Text Here</span>
</div>

      

I select the div node by name and then using the detach method to remove it:

xpathValue = "//*[contains(@name, 'divName')]"
xpath = dom.createXPath(xpathValue)
    if xpath != None:
        nodes = xpath.selectNodes(dom)
        if len(nodes) > 0:
            for node in nodes:
                node.detach()

      

This seems to remove the div fine, I noticed that it also removes the elements and text inside that div. What I'm looking for is removing the div without removing the elements and text inside the div, resulting in:

Some Text Here
<span>Some Text Here</span>

      

Is it possible to achieve this with dom4j? If there are no suggestions on how to do this?

Greetings

Eef

Update:

@alamar

I achieved what I wanted by taking your code and tweaking it a bit, and this is what I came up with:

   xpathValue = "//*[contains(@name, 'divName')]"
   xpath = dom.createXPath(xpathValue)
    if xpath != None:
        nodes = xpath.selectNodes(dom)
        if len(nodes) > 0:
            for node in nodes:
                parent = node.getParent()
                nodeContents = node.content()
                    if len(nodeContents) > 0:
                        for subNode in nodeContents:
                            parent.add(subNode.clone().detach())
            node.detach()

      

This seems to work, but adds nodes to the end of the parent node in the following situation:

<div name="parent">
    <div name="divName">
        Some Text Here
        <span>Some Text Here</span>
    </div>
    <div name="keep"></div>
</div>

      

The result will be the following:

<div name="parent">
    <div name="keep"></div>
    Some Text Here
    <span>Some Text Here</span>
</div>

      

I am trying to figure out how to get the content of the remote node so that it stays in its original position, before the div named "keep" instead of adding after the div named "keep". I have tried something but cant seem it might help, can anyone help?

Eef

+1


a source to share


3 answers


If you want to keep the order of the elements, you should really ask parent

for yours content()

. In this one content

(which is a list maintained by the parent), you have to find yours div

and replace it with a div content()

.

I don't remember an idiomatic way to do this in python, to be honest.



probably,

if xpath != None:
    nodes = xpath.selectNodes(dom)
    if len(nodes) > 0:
        for node in nodes:
            parent = node.getParent()
            index = parent.indexOf(node)
            siblings = parent.content()
            nodeContents = node.content()
                if len(nodeContents) > 0:
                    for subNode in nodeContents:
                        siblings.add(subNode.clone().detach(), index++)
        node.detach()

      

+1


a source


Try:

if xpath != None:
    nodes = xpath.selectNodes(dom)
    if len(nodes) > 0:
        for div in nodes:
            parent = div.getParent()
            div.detach()
            for(child in node.content())
                child.detach()
                parent.add(child)

      



I believe this will be the trick.

those. after detaching each div, you must re-bind each div to the parent div.

0


a source


I had a similar problem and solved it with the following function (works great for me)

What it does: It will just remove that parent tag and include every element and node inside the element to the parent at that position.

   private void _replaceTagByContent(Element element) {
        Element parent = element.getParent();
        List elements = parent.elements();
        int insertPosition = elements.indexOf(element);

        // add them all to the parent again
        for (int i = 0, size = elements.size(); i < size; i++) {
            Node node = (Node) elements.get(i);
            if (i == insertPosition) {

                // if we are here, then this has to be an element, since
                // wo do only replace elements ...

                for (int j = element.nodeCount() - 1; j >= 0; j--) {
                    Node theNode = element.node(j);
                    theNode.detach();
                    elements.add(i, theNode);
                }

                // finally remove this node
                elements.remove(node);
            }
        }
    }

      

enjoy cnsntrk

0


a source







All Articles