webentwicklung-frage-antwort-db.com.de

PHP JQuery: Konvertieren Sie HTML in JSON von der angegebenen URL und erstellen Sie eine Baumansicht der HTML-Elemente

Grundsätzlich habe ich ein Textfeld, in das ich die URL eingebe und auf "OK" klicke. Es zeigt eine Vorschau von HTML auf der linken Seite. Die rechte Seite enthält eine Baumansicht der HTML-Tags (body, header, div, span usw.), die in HTML als angefügtes Bild verwendet werden. Das erwartete JSON-Ergebnis sollte am Ende dieser Frage stehen. Ich kann JSON nicht durchlaufen und keinen Baum erstellen. Ich habe folgendes versucht:

HTML- und JS-Code:

<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ABC</title>
<link rel="stylesheet" type="text/css" href="css/main.css" />
</head>
<body>
<div id="wrapper">
    <header>
        <h1 class="logo"><img src="images/logo.png" alt="" title="" /></h1>
    </header>
    <div id="container">
        <div class="search-box">
            <input type="text" id="url" value="" class="txt-box" />
            <input type="button" value="OK" class="btn-search" />
        </div>
        <div class="inner-wrap">
            <div class="left-wrap" id="preview-sec">

            </div>
            <div class="right-wrap" id="tree-sec">

            </div>
        </div>
    </div>    
</div>

<script type="text/javascript" language="javascript" src="js/jquery-1.11.1.js"></script><!-- Jquery plugin -->
<script>
var counter = 0;
$(document).ready(function(){
    $('.btn-search').click(function(){
        if ($('#url').val() != '') {
            $.get(
                'http://localhost/test/getHTML.php', {url:$('#url').val()},
                function(response) {
                    $('#preview-sec').html(response);
            },'html');
            $.getJSON('http://localhost/test/results.json', function(json) {    
                traverse(json,0);               
            });
        }
    });
});
function traverse(obj,id){
    if (typeof(obj)=="object") {
        if (id == 0) {
            $('#tree-sec').append('<ul></ul>');
        } else {
            $(id).append('<ul></ul>');
        }
        $.each(obj, function(i,val){
            if (i != 'attributes' && i != 'value') {
                counter += 1;
                var li_populate = "<li id="+i+"-"+counter+">"+i+"</li>"; 
                if (id == 0) {
                    $('#tree-sec ul').append(li_populate);
                } else {
                    $(id).find('ul').append(li_populate);
                }
                traverse(val,"#"+i+"-"+counter);
            }
        })
    }
}
</script>
</body>
</html>

PHP Code:

<?php
    $url = $_GET['url'];
    $html = file_get_contents($url);
    function html_to_obj($html) {
        $dom = new DOMDocument();
        $dom->loadHTML($html);
        return element_to_obj($dom->documentElement);
    }

    function element_to_obj($element) {
        //print_r($element);
        $obj = array();
        $attr = array();
        $arr = array();
        $name = $element->tagName;
        foreach ($element->attributes as $attribute) {
            $attr[$attribute->name] = $attribute->value;
            if ($attribute->name == 'id') {
                $name .= '#'.$attribute->value;
            }
        }
        if (!empty($attr)) {
            $arr["attributes"] = $attr;
        }
        if ($element->nodeValue != '') {
            $arr["value"] = $element->nodeValue;
        }

        foreach ($element->childNodes as $subElement) {         
            if ($subElement->nodeType == XML_TEXT_NODE) {

            }
            elseif ($subElement->nodeType == XML_CDATA_SECTION_NODE) {

            }
            else {
                $arr["child_nodes"][] = element_to_obj($subElement);
            }
        }
        $obj[$name] = $arr;
        return $obj;
    }
    $json = json_encode(html_to_obj($html));
    $fp = fopen('results.json', 'w');
    fwrite($fp,$json);
    fclose($fp);
    echo $html;exit();
?>

JSON-Baumausgabe:

enter image description here

JSON-Ergebnis:

    {
    "html": {
        "attributes": {
            "lang": "en"
        },
        "value": "Test Development Test\r\n            *{\r\n                box-sizing:border-box;\r\n            }\r\n            body {\r\n                margin:0;\r\n                font-family: sans-serif;\r\n                color: #999;\r\n            }\r\n            a, a:visited {\r\n                text-decoration:none;\r\n            }\r\n            .movie-list .movie{\r\n                width:250px;\r\n                float:left;\r\n                margin-right:25px;\r\n            }\r\n            .movie-list .movie img{\r\n                width:100%;\r\n            }\r\n            .movie-list .movie a.title{\r\n                text-decoration:none;\r\n                color:#999;\r\n                font-weight:bold;\r\n                font-size:18px;\r\n                line-height:25px;\r\n            }\r\n            .movie-list .movie .synopsis{\r\n                font-size:14px;\r\n                line-height:20px;\r\n            }\r\n",
        "child_nodes": {
            "head": {
                "child_nodes": {
                    "meta": {
                        "attributes": {
                            "name": "description",
                            "content": "A ast of animated movies"
                        }
                    },
                    "title": {
                        "value": "Test Development Test"
                    },
                    "style": {
                        "attributes": {
                            "type": "text/css"
                        },
                        "value": "\r\n            *{\r\n                box-sizing:border-box;\r\n            }\r\n            body {\r\n                margin:0;\r\n                font-family: sans-serif;\r\n                color: #999;\r\n            }\r\n            a, a:visited {\r\n                text-decoration:none;\r\n            }\r\n            .movie-list .movie{\r\n                width:250px;\r\n                float:left;\r\n                margin-right:25px;\r\n            }\r\n            .movie-list .movie img{\r\n                width:100%;\r\n            }\r\n            .movie-list .movie a.title{\r\n                text-decoration:none;\r\n                color:#999;\r\n                font-weight:bold;\r\n                font-size:18px;\r\n                line-height:25px;\r\n            }\r\n            .movie-list .movie .synopsis{\r\n                font-size:14px;\r\n                line-height:20px;\r\n            }\r\n"
                    }
                }
            },
            "body": {
                "child_nodes": {
                    "h1": {
                        "value": "List of animated movies"
                    },
                    "div": {
                        "attributes": {
                            "class": "movie-list"
                        },
                        "child_nodes": {
                            "div#bh_6": {
                                "attributes": {
                                    "class": "movie",
                                    "id": "bh_6",
                                    "data-year": "2014"
                                },
                                "child_nodes": {
                                    "img": {
                                        "attributes": {
                                            "src": "http://ia.media-imdb.com/images/M/[email protected]_V1_SY317_CR0,0,214,317_AL_.jpg"
                                        }
                                    },
                                    "a": {
                                        "attributes": {
                                            "class": "title",
                                            "href": "http://www.imdb.com/title/tt2245084/"
                                        },
                                        "value": "Big Hero 6"
                                    },
                                    "div": {
                                        "attributes": {
                                            "class": "synopsis"
                                        },
                                        "value": "The special bond that develops between plus-sized inflatable robot Baymax, and prodigy Hiro Hamada, who team up with a group of friends to form a band of high-tech heroes."
                                    }
                                }
                            },
                            "div#tlm": {
                                "attributes": {
                                    "class": "movie",
                                    "id": "tlm",
                                    "data-year": "2014"
                                },
                                "child_nodes": {
                                    "img": {
                                        "attributes": {
                                            "src": "http://ia.media-imdb.com/images/M/[email protected]_V1_SX214_AL_.jpg"
                                        }
                                    },
                                    "a": {
                                        "attributes": {
                                            "class": "title",
                                            "href": "http://www.imdb.com/title/tt1490017/"
                                        },
                                        "value": "The Lego Movie"
                                    },
                                    "div": {
                                        "attributes": {
                                            "class": "synopsis"
                                        },
                                        "value": "An ordinary Lego construction worker, thought to be the prophesied 'Special', is recruited to join a quest to stop an evil tyrant from gluing the Lego universe into eternal stasis."
                                    }
                                }
                            },
                            "div#httyd": {
                                "attributes": {
                                    "class": "movie",
                                    "id": "httyd",
                                    "data-year": "2010"
                                },
                                "child_nodes": {
                                    "img": {
                                        "attributes": {
                                            "src": "http://ia.media-imdb.com/images/M/[email protected]@._V1_SX214_AL_.jpg"
                                        }
                                    },
                                    "a": {
                                        "attributes": {
                                            "class": "title",
                                            "href": "http://www.imdb.com/title/tt0892769/"
                                        },
                                        "value": "How to Train Your Dragon"
                                    },
                                    "div": {
                                        "attributes": {
                                            "class": "synopsis"
                                        },
                                        "value": "A hapless young Viking who aspires to hunt dragons becomes the unlikely friend of a young dragon himself, and learns there may be more to the creatures than he assumed."
                                    }
                                }
                            },
                            "div#up": {
                                "attributes": {
                                    "class": "movie",
                                    "id": "up",
                                    "data-year": "2009"
                                },
                                "child_nodes": {
                                    "img": {
                                        "attributes": {
                                            "src": "http://ia.media-imdb.com/images/M/[email protected]_V1_SX214_AL_.jpg"
                                        }
                                    },
                                    "a": {
                                        "attributes": {
                                            "class": "title",
                                            "href": "http://www.imdb.com/title/tt1049413/"
                                        },
                                        "value": "Up"
                                    },
                                    "div": {
                                        "attributes": {
                                            "class": "synopsis"
                                        },
                                        "value": "By tying thousands of balloons to his home, 78-year-old Carl sets out to fulfill his lifelong dream to see the wilds of South America. Russell, a wilderness Explorer 70 years younger, inadvertently becomes a stowaway."
                                    }
                                }
                            },
                            "div#mi": {
                                "attributes": {
                                    "class": "movie",
                                    "id": "mi",
                                    "data-year": "2001"
                                },
                                "child_nodes": {
                                    "img": {
                                        "attributes": {
                                            "src": "http://ia.media-imdb.com/images/M/[email protected]_V1_SX214_AL_.jpg"
                                        }
                                    },
                                    "a": {
                                        "attributes": {
                                            "class": "title",
                                            "href": "http://www.imdb.com/title/tt0198781/"
                                        },
                                        "value": "Monsters, Inc."
                                    },
                                    "div": {
                                        "attributes": {
                                            "class": "synopsis"
                                        },
                                        "value": "Monsters generate their city's power by scaring children, but they are terribly afraid themselves of being contaminated by children, so when one enters Monstropolis, top scarer Sulley finds his world disrupted."
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
27

Gemäß Ihrer Frage ist der Teil, in dem Sie das zurückgegebene JSON-Objekt durchlaufen und den Baum erstellen, problematisch. In Ihrem Code hatte die rekursive Funktion zum Durchlaufen der JSON-Daten einige kleinere Probleme mit dem Code generateulname__. Die Struktur des Rückgabeobjekts machte es etwas herausfordernd.

Ich konnte Ihren html/javascript Code ein wenig ändern (ohne ihn zu stark zu ändern), um den Baum auszudrucken. Der relevante Code unten:

CSS:

div#tree-sec ul ul{
    margin-left: 25px;
}
div#tree-sec ul li{
    color: #666;
}
div#tree-sec ul a{
    color: #111;
    text-decoration: underline;
    cursor: pointer;
}   
div#tree-sec ul a:hover {
    text-decoration: none;
}
div#tree-sec ul.collapsible{
    /* Custom parent styles here... */
    /* Such as a folder icon or 'plus' sign */
}

HTML & JS:

...
...
<div class="inner-wrap">
    <div class="left-wrap" id="preview-sec">
        <iframe id="preview"></iframe>
    </div>
    <div class="right-wrap" id="tree-sec">
        <ul id="treehtml1"></ul>
    </div>
</div>
....
....
<script type="text/javascript">
    var counter = 0;
    $(document).ready(function(){
        $('.btn-search').click(function(){
            if ($('#url').val() != '') {
                $.get('http://localhost/test/getHTML.php', {url:$('#url').val()}, function(response) {
                    $('#preview-sec').html(response);
                },'html');
                $.getJSON('http://localhost/test/results.json', function(json) {    
                    if(typeof(json) == "object"){
                        traverse(json,'html',1);  
                        makeCollapsible();             
                    }
                });
             }
         });
     });

     function traverse(obj, element, counter){
         for (var i in obj){
             $("#tree"+element+counter).append("<li id='"+i+counter+"'>"+i+"</li>"); // Add element to the tree
             if(obj[i].hasOwnProperty('child_nodes')){
                 $("#"+i+counter).append("<ul id='tree"+i+(counter+1)+"'></ul>"); // If there are children, add a parent ul and pass the name to subsequent recursive calls for each child
                 for(var j in obj[i].child_nodes){
                     traverse(obj[i].child_nodes[j], i, counter + 1); // Recursive call to add child
                 }
             }
          }
      }

      function makeCollapsible(){
          $('ul.parent').each(function(i) {
              var parent_li = $(this).parent('li');
              parent_li.addClass('collapsible'); //Use this selector to style your parent items...

              // Temporarily remove the list from the
              // parent list item, wrap the remaining
              // text in an anchor, then reattach it.
              var sub_ul = $(this).remove();
              parent_li.wrapInner('<a/>').children('a').click(function() {
                 // Toggle the children...
                 sub_ul.toggle();
              });
              parent_li.append(sub_ul);
          });

          // Hide all lists except the outermost.
          $('ul ul').hide();
      }
</script>
....
....

Dies sollte einen ordnungsgemäß verschachtelten ulname__-basierten Baum liefern. Wenn das Erstellen eines Abbilds des Baums eine schwierige Aufgabe ist, sollten Sie das generierte Codefragment ulkorrekt formatieren, eine HTML-Seite damit auf dem Server erstellen und dann ein serverseitiges Tool wie wkhtmltoimage aus dem verwenden wkhtmltopdf package das verwendet werden kann, um das HTML-Dokument in ein Bild zu rendern.

Eine andere Sache, die ich erwähnen möchte, ist, dass ich, anstatt das abgerufene HTML in ein Div zu laden, empfehlen würde, dass Sie einen iframeverwenden, da das abgerufene HTML dann Ihre aktuelle Seite nicht stören würde. In meinem obigen Beispiel habe ich der Vorschau iframeeinen divhinzugefügt. In einem solchen Fall können Sie php verwenden, um nur die json-Daten auszugeben, und das Festlegen der iframefür die Vorschau der URL ist so einfach wie das Zuweisen der URL wie das Attribut srcdes iframename__. So: $("#preview").prop("src", $("#url").val()).

Bearbeiten : Der Code wurde mit einem Fix aktualisiert. Es wurde auch eine neue js-Funktion makeCollapsible() hinzugefügt, um die ulnachträglich in eine anklickbare, zusammenklappbare Baumstruktur zu konvertieren, wie im Kommentar von OP angegeben. Außerdem wurden relevante CSS-Stile hinzugefügt, um die Baumstruktur zu formatieren. Der Baum sieht für mich jetzt so aus:

Collapsible, Clickable HTML Tree!

15
fijas

Nachtrag: Dies ist eine lange Antwort, die jedoch spezifische Probleme und Lösungen für die von Ihnen bereitgestellten Code-Schnipsel anspricht. Ich hoffe, Sie und andere finden es die Zeit wert zu vergleichen. :)


Ändern Sie zuerst Ihr PHP, um JSON sauberer zu machen

Beim Parsen des DOM empfehle ich, die Elementnamen aus dem zurückgegebenen Objekt als assoziative Schlüssel in $arr['child_nodes'] mithilfe von array_merge() festzulegen, anstatt sie als indizierte Elemente auf das Array zu übertragen. Dazu muss $arr['child_nodes'] zuerst als Array definiert werden. Später, wenn keine Elemente darin zusammengeführt werden, unset, bevor $arr zum Hauptobjekt hinzugefügt wird.

Dies vereinfacht das Parsen des endgültigen JSON-Ergebnisses, da beim Erstellen des Baums keine verschachtelte Schleife in Ihrem Javascript erforderlich ist.

Ich empfehle außerdem, bedingte Prüfungen für ->length einzufügen, bevor foreach-Schleifen ausgeführt werden. Ihr vorhandener Code hat Warnmeldungen ausgegeben, als Elemente mit der Länge Null in die Schleife eingegeben wurden.

Zuletzt können Sie Ihre Logik für den Umgang mit Knotentypen vereinfachen, indem Sie Ihre aktuelle if, else if, else -Anweisung durch eine einzelne if -Überprüfung für $subElement->nodeType === XML_ELEMENT_NODE ersetzen. Ich denke, Sie möchten dies erreichen.

<?php
    $url  = $_GET['url'];
    $html = file_get_contents($url);
    function html_to_obj($html) {
        $dom = new DOMDocument();
        $dom->loadHTML($html);
        return element_to_obj($dom->documentElement);
    }
    function element_to_obj($element) {
        $obj = $attr = $arr = array();
        $name = $element->tagName;
        if ($element->attributes->length) {
            foreach ($element->attributes as $attribute) {
                $attr[$attribute->name] = $attribute->value;
                if ($attribute->name == 'id') {
                    $name .= '#'.$attribute->value;
                }
            }
        }
        if (!empty($attr)) {
            $arr["attributes"] = $attr;
        }
        if ($element->nodeValue != '') {
            $arr["value"] = $element->nodeValue;
        }
        if ($element->childNodes->length) {
            $arr["child_nodes"] = array();
            foreach ($element->childNodes as $subElement) {         
                if ($subElement->nodeType === XML_ELEMENT_NODE) {
                    $arr["child_nodes"] = array_merge($arr["child_nodes"], element_to_obj($subElement));
                }
            }
            if (!count($arr["child_nodes"])) {
                unset($arr["child_nodes"]);
            }
        }
        $obj[$name] = $arr;
        return $obj;
    }
    $json = json_encode(html_to_obj($html));
    $fp   = fopen('results.json', 'w');
    fwrite($fp, $json);
    fclose($fp);
?>

Verwenden Sie einen Iframe

Fügen Sie einen leeren iframe ein, in den Sie Ihre Zielsite laden. Das Einfügen des Markups von einer anderen Site in Ihre Site kann (und wird wahrscheinlich) Konflikte mit Ihrem eigenen Code verursachen.

<div class="inner-wrap">
    <div class="left-wrap" id="preview-sec">
        <iframe src=""></iframe>
    </div>
    <div class="right-wrap" id="tree-sec">
    </div>
</div>

Vereinfachen Sie die Überquerungsfunktion und ordnen Sie asynchrone Aufrufe neu an

Die Funktion traverse hatte drei Fehler:

  1. Die Verwendung eines Zählers, um IDs im laufenden Betrieb zu erstellen und anschließend mithilfe von jQuery zuvor erstellte Elemente mit den IDs zu finden, an die Listenelemente angehängt werden, war ein Leistungsverlust und verwirrend für das Debugging.

  2. Die Verwendung von .find() führte dazu, dass jQuery redundant in den rekursiven Aufruf eintrat und dem Baum mehrfach redundante untergeordnete Knoten hinzufügte.

  3. Da es sich um den Rückruf eines separaten asynchronen Aufrufs handelt, kann er ausgeführt werden, bevor der erste asynchrone Aufruf von getHTML.php beendet wurde.

Verschieben Sie den asynchronen Aufruf, um den JSON-Code beim ersten asynchronen Aufruf in die Rückruffunktion zu versetzen und zu verhindern, dass unvollständiger oder alter JSON-Code vom Server abgerufen wird.

Sie sollten diesen ersten Rückruf auch verwenden, um iframesrc festzulegen und den Container #tree-sec zu leeren, damit nachfolgende Aktionen nicht mehr als einen Baum anhängen. Sie können dasselbe erreichen, indem Sie .replace() anstelle von .empty() gefolgt von .append() verwenden.

Um den Baum zu erstellen, empfehle ich den folgenden einfacheren Ansatz, bei dem die Liste rekursiv als Zeichenfolge erstellt wird, sodass die .append-Methode nur einmal aufgerufen wird. Bei größeren Bäumen wird dadurch die Leistung erheblich verbessert.

Sie können dieser Funktion einen Zähler und dynamisch zugewiesene IDs hinzufügen, wenn Sie möchten, aber ich habe darauf verzichtet, um klarer zu zeigen, dass sie nicht zum Erstellen des Baums benötigt werden.

Ich empfehle außerdem, vor dem Eingeben eines rekursiven Aufrufs zu prüfen, ob untergeordnete Knoten vorhanden sind. Bei dieser Prüfung können Sie nur das untergeordnete Nodes-Objekt übergeben, das aufgrund des neuen JSON-Codes, der sich aus Änderungen am Skript PHP ergibt, jetzt Tag-Namen als Schlüssel enthält, anstatt indizierte Schlüssel mit den Elementen als Kinder. Wenn wir den JSON nicht vereinfacht hätten, wäre an dieser Stelle eine zweite Schleife erforderlich gewesen, um jedes Element abzurufen.

Sie werden auch feststellen, dass die Attribute aria- und role enthalten sind. Auf diese Weise sind Sie bei Bedarf vollständig erreichbar.

Siehe: Verwendung des erweiterten WAI-ARIA-Arienstatus zum Markieren erweiterbarer und reduzierbarer Regionen (w3.org)

Es bietet Ihnen auch eine praktische und semantische Möglichkeit, CSS und den Toggle-Status zu steuern. Dies wird im zusätzlichen Click-Handler am Ende des Skripts und im CSS-Beispiel am Ende dieser Antwort demonstriert.

$(document).ready(function () {
    function traverse(data, firstTime) {
        if (typeof data === 'object') {  
            var ul = '<ul role="' + (firstTime ? 'tree' : 'group' ) + '">';
            $.each(data, function (key, val) {
                if (key !== 'attributes' && key !== 'value') {
                    if (val['child_nodes']) {
                        ul += '<li aria-expanded="true" role="tree-item" tabindex="0">';
                        ul += key;
                        ul += traverse(val['child_nodes']);
                        ul += '</li>';
                    } else {
                        ul += '<li role="tree-item" tabindex="0">';
                        ul += key;
                        ul += '</li>';
                    }
                }
            });
            ul += '</ul>';
            return ul;
        }
    }
    $('.btn-search').on('click', function () {
        var url = $('#url').val();
        if (url) {
            $.get(
                'getHTML.php',
                {
                    url: url
                },
                function () {
                    $('#preview-sec iframe').attr('src', url);
                    $('#tree-sec').empty();
                    $.get(
                        'results.json',
                        function (json) {
                            $('#tree-sec').append(traverse(json, true));
                        },
                        'json'
                    );
                },
                'html'
            );
        }
    });
    $('#tree-sec').on('click', 'li[aria-expanded]', function (e) {
        e.stopPropagation();
        $(this)
            .attr('aria-expanded', function (i, attr) {
                return !(attr === 'true');
            })
            .children('ul')
            .attr('aria-hidden', function (i, attr) {
                return !(attr === 'true');
            })
            .toggle();
    });
});

Bonus: Verwenden Sie Attributselektoren im CSS

Schließlich bietet, wie oben erwähnt, das Vorhandensein der Attribute aria- und role eine semantische und bequeme Möglichkeit, die Stile zu steuern.

ul[role='tree'] {
    margin-left: 1em;
    padding-left: 0;
}
ul[role='tree'] li {
    cursor: default;
    margin: 0;
    padding: 0 0 0 20px;
    font: normal 1em sans-serif;
    color: #333;
}
ul[role='tree'] li[aria-expanded] {
    cursor: pointer;
    font-weight: bold;
    color: #111;
    background: transparent 0 0 no-repeat url('images/arrow-Sprite.png');
}
ul[role='tree'] li[aria-expanded="true"] {
    background-position: 0 0;
}
ul[role='tree'] li[aria-expanded="false"] {
    background-position: 0 20px;
}
4
gfullam

Schauen Sie sich diese Bibliothek an die von Jack geschrieben wurde.

https://github.com/Jxck/html2json

Hoffe es hilft dir.

1
Touqeer Shafi

Konstruieren Sie ein mehrdimensionales PHP -Array für Ihre HTML-Tags und geben Sie dieses Array als Eingabe für die in PHP eingebaute Funktion json_encode ($ array) ein. Dadurch wird eine baumstrukturierte json-Ausgabe zurückgegeben

0
Sagar

Schauen Sie sich die XSLT-Verarbeitung an. funktioniert gut mit viel weniger Code-Aufwand

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="json.xml"?>
<html>
<body>
    <h1>title</h1>
    <h2>title 2</h2>
    <h3>title 3</h3>
    <ul>
        <li>t1</li>
        <li>t2</li>
        <li>t3</li>
    </ul>
</body>
</html>

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template name="json" match="/">
<xsl:for-each select="*">
{"<xsl:value-of select="local-name()"/>": "<xsl:if test="count(*)=0"><xsl:value-of select="text()"/></xsl:if>",
"attributes": {<xsl:for-each select="@*"><xsl:if test="position()>1">,</xsl:if>"<xsl:value-of select="local-name()"/>": "<xsl:value-of select="text()"/>"</xsl:for-each>},<xsl:call-template name="json"/>}</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
0
user1587368