XSLTПроцессор не работает

Я ломал голову, пытаясь понять, почему следующий вызов XSLTProcessor не работает.

XSL-Т

<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xml:space = "default">
    <xsl:output method = "text" version = "1.0" encoding = "UTF-8" indent = "no"/>
    <xsl:strip-space elements = "*"/>
    <xsl:param name = "include-header" select = "'false'"/>
    <xsl:template match = "/">
       <!--xsl:element name = "row"-->
       <xsl:text>{</xsl:text>
        <xsl:apply-templates select = "*"/>
        <!--/xsl:element-->
       <xsl:text>}</xsl:text>
    </xsl:template>
    <xsl:template match = "*[count(descendant::*)=0]">
        <xsl:param name = "parent"/>
        <xsl:variable name = "quote" select = "'&quot;'"/>
        <xsl:variable name = "thisName" select = "name()"/>
        <xsl:variable name = "precedingSibling" select = "count(preceding-sibling::*[name()=$thisName])+1"/>
        <xsl:variable name = "parentChild" select = "concat($parent, '.',$thisName, $precedingSibling)"/>
        <xsl:value-of select = "concat($quote,$parentChild, $quote, ': ', $quote, ., $quote, ',')"/>
        <xsl:text>
</xsl:text>
    </xsl:template>
    <xsl:template match = "*">
        <xsl:call-template name = "recurse-descendents"/>
    </xsl:template>
    <xsl:template match = "*[count(descendant::*)>0]">
        <xsl:call-template name = "recurse-descendents"/>
    </xsl:template>
    <xsl:template name = "recurse-descendents">
        <xsl:variable name = "thisName" select = "name()"/>
        <xsl:apply-templates select = "*[count(descendant::*)=0]">
            <xsl:with-param name = "parent" select = "concat($thisName, count(preceding-sibling::*[name()=$thisName])+1)"/>
        </xsl:apply-templates>
        <xsl:apply-templates select = "*[count(descendant::*)>0]"/>
    </xsl:template>
</xsl:stylesheet>

Пример XML

<?xml version = "1.0" encoding = "UTF-8"?>
<foods>
    <meats>
        <meat>Beef</meat>
        <meat>Chicken</meat>
        <meat>Lamb</meat>
    </meats>
    <fruits>
        <fruit>Orange</fruit>
        <fruit>Apple</fruit>
        <fruit>Banana</fruit>
        <fruit>Avacado</fruit>
    </fruits>
    <vegetables>
        <vegetable>Carrot</vegetable>
        <vegetable>Cellery</vegetable>
        <vegetable>Potato</vegetable>
    </vegetables>
</foods>

Вывод из XML Spy (как и ожидалось)

{"meats1.meat1": "Beef",
"meats1.meat2": "Chicken",
"meats1.meat3": "Lamb",
"fruits1.fruit1": "Orange",
"fruits1.fruit2": "Apple",
"fruits1.fruit3": "Banana",
"fruits1.fruit4": "Avacado",
"vegetables1.vegetable1": "Carrot",
"vegetables1.vegetable2": "Cellery",
"vegetables1.vegetable3": "Potato",
}

Код Javascript с использованием XSLTProcessor (не работает)

async function GenerateTestCaseResponse(xml, testCase) {
    const domParser = new DOMParser();
    const xsltProcessor = new XSLTProcessor();

    const xslResponse = await fetch("transformer/generate-response-json.xslt");
    const xslText = await xslResponse.text();
    const xslStylesheet = domParser.parseFromString(xslText, "application/xml");
    xsltProcessor.importStylesheet(xslStylesheet);
    var responseDomParser = new DOMParser();
    var responseDocument = responseDomParser.parseFromString(xml, "text/xml");
    var result =  xsltProcessor.transformToDocument(responseDocument);
    console.info(result.body);
    return result;
}

Вызов xsltProcessor.transformToDocument возвращает пустой результат без ошибок или исключений. Не знаю, как решить, и любые мысли принимаются с благодарностью.

Возможно, вы неправильно вызываете свою функцию GenerateTestCaseResponse?

Jaromanda X 15.03.2024 06:54

нет, отлаженный вызов браузера правильный + переданный xml действителен. Также подтверждено, что XSLT загружен.

Andrew Tyson 15.03.2024 06:57

с чего ты взял, что будет .body? то, что вы ищете, находится в result.firstElementChild.textContent

Jaromanda X 15.03.2024 07:05
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как уже указывалось в комментарии, в произвольных XML-документах нет тела. Кажется, вы все равно хотите использовать текст метода вывода и текстовое содержимое, поэтому используйте результат фрагмента и получите доступ к его свойству textContent, например.

const xsltSource = `<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xml:space = "default">
    <xsl:output method = "text" version = "1.0" encoding = "UTF-8" indent = "no"/>
    <xsl:strip-space elements = "*"/>
    <xsl:param name = "include-header" select = "'false'"/>
    <xsl:template match = "/">
       <!--xsl:element name = "row"-->
       <xsl:text>{</xsl:text>
        <xsl:apply-templates select = "*"/>
        <!--/xsl:element-->
       <xsl:text>}</xsl:text>
    </xsl:template>
    <xsl:template match = "*[count(descendant::*)=0]">
        <xsl:param name = "parent"/>
        <xsl:variable name = "quote" select = "'&quot;'"/>
        <xsl:variable name = "thisName" select = "name()"/>
        <xsl:variable name = "precedingSibling" select = "count(preceding-sibling::*[name()=$thisName])+1"/>
        <xsl:variable name = "parentChild" select = "concat($parent, '.',$thisName, $precedingSibling)"/>
        <xsl:value-of select = "concat($quote,$parentChild, $quote, ': ', $quote, ., $quote, ',')"/>
        <xsl:text>
</xsl:text>
    </xsl:template>
    <xsl:template match = "*">
        <xsl:call-template name = "recurse-descendents"/>
    </xsl:template>
    <xsl:template match = "*[count(descendant::*)>0]">
        <xsl:call-template name = "recurse-descendents"/>
    </xsl:template>
    <xsl:template name = "recurse-descendents">
        <xsl:variable name = "thisName" select = "name()"/>
        <xsl:apply-templates select = "*[count(descendant::*)=0]">
            <xsl:with-param name = "parent" select = "concat($thisName, count(preceding-sibling::*[name()=$thisName])+1)"/>
        </xsl:apply-templates>
        <xsl:apply-templates select = "*[count(descendant::*)>0]"/>
    </xsl:template>
</xsl:stylesheet>`;

const xmlSource = `<?xml version = "1.0" encoding = "UTF-8"?>
<foods>
    <meats>
        <meat>Beef</meat>
        <meat>Chicken</meat>
        <meat>Lamb</meat>
    </meats>
    <fruits>
        <fruit>Orange</fruit>
        <fruit>Apple</fruit>
        <fruit>Banana</fruit>
        <fruit>Avacado</fruit>
    </fruits>
    <vegetables>
        <vegetable>Carrot</vegetable>
        <vegetable>Cellery</vegetable>
        <vegetable>Potato</vegetable>
    </vegetables>
</foods>`;


function GenerateTestCaseResponse(xmlSource, xsltSource) {
    const domParser = new DOMParser();
    const xsltProcessor = new XSLTProcessor();

    const xsltStylesheet = domParser.parseFromString(xsltSource, "application/xml");
    xsltProcessor.importStylesheet(xsltStylesheet);
    
    var xmlDoc = domParser.parseFromString(xmlSource, "application/xml");
    var result = xsltProcessor.transformToFragment(xmlDoc, xmlDoc).textContent;
    
    console.info(result);
    return result;
}

GenerateTestCaseResponse(xmlSource, xsltSource);

Другие вопросы по теме