My convenient bike (Javascript interface) for navigating an XML document

    I have such fun - the "bike." No, this is not about an environmentally friendly form of transport. I like to come up with something new. But when the topic is already hackneyed, and the problem has already been solved so many times in all sorts of variations, the search for a new, but yet another solution is a “bicycle”. Well, you understand. Another bike ... In practice, for me, this is one of the main ways of learning.

    I decided to thoroughly deal with JavaScript (before that I used it often, but exclusively for needs, with bioadditives and vitamins, in the form of a dish called JQuery). The result seemed interesting to me, but, in connection with reading about ElementTraversal , I decided that it might be interesting to someone else too ... About how I survived before ...

    from = new Target;

    // получить предпоследний дочерний элемент для следующего за текущим
    node = from.next().inner().previous().previous().get();





    I have such fun - the "bike." No, this is not about an environmentally friendly form of transport. I like to come up with something new. But when the topic is already hackneyed, and the problem has already been solved so many times in all sorts of variations, the search for a new, but yet another solution is a “bicycle”. Well, you understand. Another bike ... In fact, for me, this is one of the main ways of learning.

    The first thing I want to say is that I am not a programmer (although I have a university degree in computer technology). I’m a designer (officially called an art director now, but the essence is the same), in the broadest sense of the word (and not a graphic designer, with whom it is customary in this country to associate this profession, although, again, I have a secondary art education and about twenty certificates in various crafts, which he studied in his school years). Simply put, my main professional skill is the ability to find an original, and ideally optimal, solution to the problem. And, the “bicycle” is an integral part of the process. And the purpose of this lyrical digression is to try to draw your attention, not to the characteristics of the attached code, but to the characteristics of the proposed approach.

    Initially, of course, due to the need for lotto and gymnasium students (so that cross-browser and if necessary could still be used in other languages, after minimal modification), I decided to use the DOM for these purposes (you might think there were more options). After disposing of the corresponding waste paper, on the topic “How Others Live,” I realized that there are not many approaches, besides using the DOM in its pure form, which is rather tedious: five corresponding functions from John Resign’s book “ProJavaScript”, already mentioned by ElementTraversal (in fact, the same five functions plus one more, to get the number of children), well, or trying to look at XML Simple in PHP. As for me, either it is possible and more clearly, or less monstrously.

    Then there were creative torment (as an integral part of the creative process), periodically interrupted by exclamations: “Ssssss ... ah! Why doesn’t it work! ” And so on, which is hardly of interest to you. So, finally, the result.

    A class for storing a link to an element and the necessary functions for working with it (the root element of the document is set by default): A method for finding the element preceding the current one (or the element passed to the method as a parameter), with the correction that the set is considered cyclic, that is, the last element in the set is considered the previous with respect to the first: A method for finding the element following the current one (or the method passed as a parameter), by its action, the opposite of the one described earlier:

    // Target
    Target = function ( element ) {
    var _element = element || document.documentElement;
    this.get = function () { return _element }
    this.set = function ( element ) { _element = element || document.documentElement }
    }




    // previous
    Target.prototype.previous = function ( element ) {
    var element = element || this.get();
    if( element != document.documentElement.parentNode ) {
    element = element.previousSibling || element.parentNode.lastChild;
    while( element && element.nodeType != 1 ) { element = element.previousSibling }
    }
    this.set( element );
    return this;
    }




    // next
    Target.prototype.next = function ( element ) {
    var element = element || this.get();
    if( element != document.documentElement.parentNode ) {
    element = element.nextSibling || element.parentNode.firstChild;
    while( element && element.nodeType != 1 ) { element = element.nextSibling }
    }
    this.set( element );
    return this;
    }


    Method for finding the parent (external) element, relative to the current (or passed method as a parameter): Method for finding the first child (internal) element, relative to the current (or passed method as a parameter): Methods change the link inside the instance class value which can be obtained, as can be seen from the code using the get () method and set using the set () method. They return the object itself as their work (oh yes, JQuery injured my psyche, and not only mine, I think). Result:

    // outer
    Target.prototype.outer = function ( element ) {
    var element = element || this.get();
    if( element.parentNode != document.documentElement.parentNode ) { element = element.parentNode }
    this.set( element );
    return this;
    }




    // inner
    Target.prototype.inner = function ( element ) {
    var element = element || this.get();
    if( element.childNodes.length != 0 ) {
    for( var i = 0; i < element.childNodes.length; i++ ) {
    if( element.childNodes.item( i ).nodeType == 1 ) {
    element = element.childNodes.item( i );
    break;
    }
    }
    }
    this.set( element );
    return this;
    }






    from.next().inner().previous().previous().get();

    Then, after using it in practice (in subsequent experiments with JavaScript, and later with the transfer of this mechanics to Ruby and PHP, where I used it in parsing XML documents), another method appeared that I see (or rather, the format of the template passed to it in as a parameter) and is what may be of interest to you (and therefore the reason for writing this article on Habré). A method for performing a sequence of actions according to a template (similar to “the first carriage from the center, to the left, to the left, to the post, there will be one on the right”), in which the transition to the parent element corresponds to the symbol “<”, the first child “>” preceding “- ", The next" + "(example: the chain .outer (). Next (). Inner (). Previous (). Previous () matches the template" <+> - "): The previous example can be rewritten as follows:

    // select
    Target.prototype.select = function ( path ) {
    var steps = path.split( "" );
    for( var i = 0; i < steps.length; i++ ) {
    if( steps[ i ] == "-" ) { this.previous() }
    if( steps[ i ] == "+" ) { this.next() }
    if( steps[ i ] == "<" ) { this.outer() }
    if( steps[ i ] == ">" ) { this.inner() }
    }
    return this;
    }




    from = new Target;

    // a, гулять, так гулять (инновации, так инновации), аналог первой записи
    node = from.select( “+>--” ).get();


    Afterword: there is an idea to add the ability to specify the number of iterations in the template (so that you can write “> 3 + 6” instead of “>>> ++++++”), but have not yet implemented it.

    One more afterword: in general, who cares about similar epics, is it worth writing like this from now on, or is there no place for such lyrics on Habré?

    Also popular now: