Как я могу использовать JavaScript для преобразования XML и XSLT? - PullRequest
10 голосов
/ 20 апреля 2011

Я хочу использовать JavaScript для отображения моего XSLT, но на моем сервере в браузере ничего не отображается.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script type="text/javascript" src="main.js"></script>
<meta http-equiv="Content-Language" content="en-us"/>
<title>Contracting, Licensing and Compliance News</title>
</head>
<body>
<script language="javascript">
    function displayMessage() {
        // Load XML 

        var xml = new ActiveXObject("Microsoft.XMLDOM")
        xml.async = false
        xml.load("site-index.xml")

        // Load the XSL
        var xsl = new ActiveXObject("Microsoft.XMLDOM")
        xsl.async = false
        xsl.load("site-index.xsl")

        // Transform
        document.write(xml.transformNode(xsl))
    }
</script>
</body>
</html>

Ответы [ 5 ]

31 голосов
/ 20 апреля 2011

Возможно, вам лучше разрешить браузеру выполнить преобразование, используя метод, описанный Xenan.Тем не менее, это вполне возможно сделать и в JavaScript.Вот схема того, как вы могли бы сделать это кросс-браузерным способом.

Во-первых, вам нужно будет загрузить XML и XSL.Есть много способов сделать это.Обычно, это будет включать в себя какой-то AJAX, но не обязательно.Чтобы этот ответ был простым, я предполагаю, что вы рассмотрели эту часть, но, пожалуйста, дайте мне знать, если вам нужна дополнительная помощь, и я отредактирую, чтобы включить пример загрузки XML.

Поэтому, давайте предположим, что мыимеют следующие объекты:

var xml, xsl;

Где xml содержит структуру XML, а xsl содержит таблицу стилей, с которой вы хотите преобразовать.


Редактировать:

Если вам нужно загрузить эти объекты, вы в конечном итоге будете использовать какую-то форму AJAX для этого.Существует множество примеров кросс-браузерного AJAX.Вам будет лучше использовать библиотеку для достижения этой цели, а не использовать собственное решение.Я предлагаю вам изучить jquery или YUI, которые отлично справляются с этой задачей.

Однако основная идея довольно проста.Чтобы завершить этот ответ, вот некоторый не специфичный для библиотеки код, который выполняет это кросс-браузерным способом:

function loadXML(path, callback) {
    var request;

    // Create a request object. Try Mozilla / Safari method first.
    if (window.XMLHttpRequest) {
        request = new XMLHttpRequest();

    // If that doesn't work, try IE methods.
    } else if (window.ActiveXObject) {
        try {
            request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e1) {
            try {
                request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e2) {
            }
        }
    }

    // If we couldn't make one, abort.
    if (!request) {
        window.alert("No ajax support.");
        return false;
    }

    // Upon completion of the request, execute the callback.
    request.onreadystatechange = function () {
        if (request.readyState === 4) {
            if (request.status === 200) {
                callback(request.responseXML);
            } else {
                window.alert("Could not load " + path);
            }
        }
    };

    request.open("GET", path);
    request.send();
}

Вы могли бы использовать этот код, указав ему путь к вашему XML и функцию длявыполнить после завершения загрузки:

loadXML('/path/to/your/xml.xml', function (xml) {
    // xml contains the desired xml document.
    // do something useful with it!
});

Я обновил свой пример, чтобы показать эту технику.Вы можете найти рабочий демонстрационный код здесь .


Чтобы выполнить преобразование, вы получите третий XML-документ, который является результатом этого преобразования.Если вы работаете с IE, вы используете метод " transformNodeToObject ", а если вы работаете с другими браузерами, вы используете метод " transformToDocument ":

var result;

// IE method
if (window.ActiveXObject) {
    result = new ActiveXObject("MSXML2.DOMDocument");
    xml.transformNodeToObject(xsl, result);

// Other browsers
} else {
    result = new XSLTProcessor();
    result.importStylesheet(xsl);
    result = result.transformToDocument(xml);
}

На этом этапе result должно содержать результирующее преобразование.Это все еще документ XML, и вы должны относиться к нему как к такому.Если вам нужна строка, которую вы можете передать в document.write или innerHTML, у вас есть немного больше работы.

Еще раз, есть метод IE для этого и метод, который применяется кдругие браузеры.

var x, ser, s = '';

// IE method.
if (result.childNodes[0] && result.childNodes[0].xml) {
    for (x = 0; x < result.childNodes.length; x += 1) {
        s += result.childNodes[x].xml;
    }
// Other browsers
} else {
    ser = new XMLSerializer();
    for (x = 0; x < result.childNodes.length; x += 1) {
        s += ser.serializeToString(result.childNodes[x]);
    }
}

Теперь s должен содержать полученный XML-код в виде строки.Вы должны быть в состоянии передать это в document.write или innerHTML и сделать что-то полезное.Обратите внимание, что он может содержать декларацию XML, которую вы, возможно, захотите удалить или нет.

Я проверял это в Chrome, IE9 и FF4.Вы можете найти упрощенный рабочий пример этого на моем тестовом стенде .

Удачи и удачного кодирования!

7 голосов
/ 20 апреля 2011

Браузер может выполнить преобразование для вас.Никакой javascript не требуется, просто свяжите .xsl с .xml следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="site-index.xsl" ?>

и просто предоставьте XML, без HTML.Предполагая, что ваш .xsl содержит правильный код, вдоль строк

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="4.01" indent="yes"/>
<xsl:output doctype-system="http://www.w3.org/TR/html4/strict.dtd"/>
<xsl:output doctype-public="-//W3C//DTD HTML 4.01//EN"/>
6 голосов
/ 22 апреля 2016

Используйте этот сценарий для преобразования test.xml с использованием test.xsl и добавления вывода в контейнер .

 <div id="container"></div>
 <script>
     function loadXMLDoc(filename) {
        if (window.ActiveXObject) {
             xhttp = new ActiveXObject("Msxml2.XMLHTTP");
        } else {
             xhttp = new XMLHttpRequest();
        }
        xhttp.open("GET", filename, false);
        xhttp.send("");
        return xhttp.responseXML;
     }

     xml = loadXMLDoc("test.xml");
     xsl = loadXMLDoc("test.xsl");
     if (document.implementation && document.implementation.createDocument) {
        xsltProcessor = new XSLTProcessor();
        xsltProcessor.importStylesheet(xsl);
        resultDocument = xsltProcessor.transformToFragment(xml, document);
        document.getElementById('container').appendChild(resultDocument);
     }
 </script>
0 голосов
/ 13 ноября 2018

Просто комментарий в виде ответа из-за низкой репутации. если вы получаете документы через AJAX, DO возвращает xhttp.responseXML и НЕ возвращают xhttp.responseXML.documentElement.

Оба могут быть преобразованы с помощью XMLSerializer в значимое представление документа, но только первый оператор является жизнеспособным параметром для преобразования XSL.

Если используется последний, возвращаемое значение XSLTransformation (с использованием функции toDocument или toFragment) в моем случае составляет null (с использованием Chrome)

В этом отношении я не верю, что Chrome прекратил поддержку XSLT, как указано где-то здесь на странице.

Надеюсь, это поможет

0 голосов
/ 06 ноября 2017

Это работает в Chrome / Firefox / Edge / IE11

 function loadXMLDoc(filename) {
     if (window.ActiveXObject || "ActiveXObject" in window) {
         xhttp = new ActiveXObject("Msxml2.XMLHTTP");
     } else {
         xhttp = new XMLHttpRequest();
     }
     xhttp.open("GET", filename, false);
     xhttp.send("");
     return xhttp.responseXML;
 }


 if (window.ActiveXObject || "ActiveXObject" in window) {
     ie();
 } else {

     xml = loadXMLDoc("input.xml");
     xsl = loadXMLDoc("mmlctop2_0.xsl");

     if (document.implementation && document.implementation.createDocument) {
         xsltProcessor = new XSLTProcessor();
         xsltProcessor.importStylesheet(xsl);
         resultDocument = xsltProcessor.transformToDocument(xml, document);

         var serializer = new XMLSerializer();
         var transformed = serializer.serializeToString(resultDocument.documentElement);

         alert(transformed);
     }
 }

 // https://msdn.microsoft.com/en-us/library/ms753809(v=vs.85).aspx
 function ie() {

     var xslt = new ActiveXObject("Msxml2.XSLTemplate.3.0");
     var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.3.0");
     var xslProc;
     xslDoc.async = false;
     xslDoc.load("mmlctop2_0.xsl");
     if (xslDoc.parseError.errorCode != 0) {
         var myErr = xslDoc.parseError;
         alert("You have error " + myErr.reason);
     } else {
         xslt.stylesheet = xslDoc;
         var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.3.0");
         xmlDoc.async = false;
         xmlDoc.load("input.xml");
         if (xmlDoc.parseError.errorCode != 0) {
             var myErr = xmlDoc.parseError;
             alert("You have error " + myErr.reason);
         } else {
             xslProc = xslt.createProcessor();
             xslProc.input = xmlDoc;
             xslProc.addParameter("param1", "Hello");
             xslProc.transform();
             alert(xslProc.output);
         }
     }


 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...