Re: How to reorder DOM nodes in tdom?



On Feb 24, 4:34 am, "MartinLemburg@Siemens-PLM"
<martin.lemburg.siemens-...@xxxxxxx> wrote:
Hi,

since there seems to be no way to sort the DOM tree in tdom, what's
about this:

    proc sortCommand {nodeValueCommand options node1 node2} {
        # get the values to compare
        #
        set value1 [{*}[string map [list %N $node1]
$nodeValueCommand]];
        set value2 [{*}[string map [list %N $node2]
$nodeValueCommand]];

        # care for the nocase option
        #
        if {"-nocase" in $options} {
            set value1 [string tolower $value1];
            set value2 [string tolower $value2];
        }

        # compare in dictionary style
        #
        if {"-dictionary" in $options} {
            if {$value1 eq $value2} {
                return 0;
            }

            set list [lsort -dictionary [list $value1 $value2]];

            if {$value1 eq [lindex $list 0]} {
                return -1;
            }

            return 1;
        }

        # compare non-numerical values
        #
        if {   ("-real" ni $options && "-integer" ni $options)
            || ![string is double -strict $value1]
            || ![string is double -strict $value2]} {
            return [string compare $value1 $value2];
        }

        # compare numerical values
        #
        if {$value1 == $value2} {
            return 0;
        } elseif {$value1 > $value2} {
            return 1;
        }

        return -1;
    }

    proc sortNodesByCommand {parentNode nodeValueCommand args} {
        # get the child nodes and sort them
        #
        set childNodes  [$parentNode childNodes];
        set sortedNodes [lsort \
            {*}$args \
            -command [list sortCommand $nodeValueCommand $args] \
            $childNodes \
        ];

        if {$sortedNodes eq $childNodes} {
            return;
        }

        # remove all child nodes from the parent node
        #
        foreach childNode $childNodes {
            $parentNode removeChild $childNode;
        }

        # add the child nodes in the new order
        #
        foreach childNode $sortedNodes {
            $parentNode appendChild $childNode;
        }

        return;
    }

    proc sortNodesByName {parentNode args} {
        sortNodesByCommand $parentNode {%N nodeName} {*}$args -
dictionary;
    }

    proc sortNodesByValue {parentNode args} {
        sortNodesByCommand $parentNode {%N nodeValue} {*}$args;
    }

    proc sortNodesByText {parentNode args} {
        sortNodesByCommand $parentNode {%N text} {*}$args -dictionary;
    }

    proc sortNodesByAttribute {parentNode attribute args} {
        sortNodesByCommand $parentNode {%N getAttribute $attribute} {*}
$args;
    }

    # examples
    #
    package require tdom;

    set dom [dom parse -html [tDOM::xmlReadFile $htmlFile]];
    set doc     [$dom documentElement];
    set head    [$doc firstChild];

    sortNodesByName $head;
    sortNodesByCommand $body {llength [%N childNodes]};

I've put this to the wiki, too:http://wiki.tcl.tk/25772

Best regards,

Martin

On 23 Feb., 19:42, max vorticity <max.vortic...@xxxxxxxxxxx> wrote:

I would like to reorder rows in an html table so I thought it might be
good time to learn how to use tdom instead of brute force parsing of
the html with string commands, but now I've spent a bit more time than
I should have to do this.  I can get a list of nodes in the order I
want, but I'm not sure how to change the parent's child list  to be in
this order.  Do I first clone the parent node and add in each child in
order,  use insertBefore or replaceChild?  For the latter two, I was
unsure if I needed to be concerned with the document fragment list the
documentation mentions.   I sure this is fairly straight forward, but
I don't really have much knowledge of working with trees or DOM.



I found that just reusing the node with appendChild reordered the
nodes. So if $nodes is a list of the nodes in the desired order:

foreach n $nodes {$parent appendChild $n}

The above worked in my case but I don't know if this is really a safe
way to reoder the nodes.
.



Relevant Pages

  • Re: Additional tDom character conversions
    ...      You may recall that I like to generate XHTML via tDom. ... and found that tDom didn't seem to ... the "List of XML and HTML character entity references" on Wikipedia - I ... % dom createDocument foo doc ...
    (comp.lang.tcl)
  • Re: Weird tdom bug?
    ... might help you to reproduce it including a sample xml file: ...  dom parse [read $xfile] xdoc ... For those of us unfamiliar with Tdom, ...
    (comp.lang.tcl)
  • Re: Converting an output to XML
    ... I don't have much experience in tDom. ... table in XML format. ...   Name   points ... Anil Kumar Akuthota ...
    (comp.lang.tcl)