XSLTProcessor 未运行

问题描述 投票:0回答:1

一直在绞尽脑汁试图找出为什么以下 XSLTProcessor 调用不起作用。

XSL-T

<?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",
}

使用 XSLTProcessor 的 Javascript 代码(不起作用)

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.log(result.body);
    return result;
}

xsltProcessor.transformToDocument
的调用返回空,没有错误或异常。不知如何解决,如有任何想法,感激不尽。

javascript xml xslt
1个回答
0
投票

正如评论中已经指出的,任意 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.log(result);
    return result;
}

GenerateTestCaseResponse(xmlSource, xsltSource);

© www.soinside.com 2019 - 2024. All rights reserved.