Xml XSLT文档函数在chrome中不起作用

Xml XSLT文档函数在chrome中不起作用,xml,google-chrome,xslt,Xml,Google Chrome,Xslt,我正在尝试使用Javascript转换XSLT,并尝试使其在Chrome和IE上都能工作。入口页面是a.html。它在IE原生/兼容模式下都可以正常工作,但在Chrome中无法正常工作,即下拉菜单没有使用选项创建 但是,在chrome中,如果我打开data.xml,它具有: <?xml-stylesheet type="text/xsl" href="render.xslt" ?> foo/b.xml: <dropdowns> <dropdown name="

我正在尝试使用Javascript转换XSLT,并尝试使其在Chrome和IE上都能工作。入口页面是a.html。它在IE原生/兼容模式下都可以正常工作,但在Chrome中无法正常工作,即下拉菜单没有使用选项创建

但是,在chrome中,如果我打开data.xml,它具有:

<?xml-stylesheet type="text/xsl" href="render.xslt" ?>
foo/b.xml:

<dropdowns>
  <dropdown name="xyz">
    <option value="I">Info</option>
    <option value="C">Category</option>
  </dropdown>
</dropdowns>
data.xml:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="render.xslt" ?>
<catalog name="xyz" />
a、 html:

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="jquery-3.3.1.js"></script>
    <title>Document</title>
</head>

<body>
    <div id="example"></div>
    <script src="b.js"></script>
</body>

</html>
render.xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:import href="util.xslt" />
    <xsl:output method="html"></xsl:output>
    <xsl:template match="/">
        <h1>
            <xsl:value-of select="/catalog/@name"></xsl:value-of>
        </h1>
        <xsl:call-template name="dropdown">
            <xsl:with-param name="listname">xyz</xsl:with-param>
            <xsl:with-param name="value" select="/catalog/@name"/>
        </xsl:call-template>
    </xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="util.xslt" />
<xsl:output method="html"></xsl:output>
<xsl:template match="/">
    <h1>
        <xsl:value-of select="/catalog/@name"></xsl:value-of>
    </h1>
    <xsl:call-template name="dropdown">
        <xsl:with-param name="listname">xyz</xsl:with-param>
        <xsl:with-param name="value">C</xsl:with-param>
    </xsl:call-template>
</xsl:template>
</xsl:stylesheet>
util.xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"></xsl:output>
    <xsl:template name="dropdown">
        <xsl:param name="listname"/>
        <xsl:param name="value"/>
        <select>
            <xsl:for-each select="document('foo/b.xml')/dropdowns/dropdown[@name=$listname]/option">
                <option>
                    <xsl:attribute name="value">
                        <xsl:value-of select="@value"/>
                    </xsl:attribute>
                    <xsl:value-of select="."/>
                </option>
            </xsl:for-each>
        </select>
    </xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="foo/b.xslt" />
<xsl:output method="html" />

<xsl:template name="dropdown">
    <xsl:param name="listname"/>
    <xsl:param name="value"/>
    <select>
        <xsl:call-template name="dropdowns">
            <xsl:with-param name="listname" select="$listname"/>
            <xsl:with-param name="value" select="$value"/>
        </xsl:call-template>
    </select>
</xsl:template>
</xsl:stylesheet>
很抱歉,作为一个MVE示例有点长,但它是完整的


如果需要任何澄清,请告诉我。

一般来说,整个方法都是关于嵌套模板的。 这里已经回答了这个问题:

以下仍然是一些问题和对问题下方评论的澄清

调整了本地服务器,使其将文件util.xslt作为chrome所期望的内容类型text/css而不是application/xslt+xml来交付,脚本仍然无法像预期的那样工作。因此,一定还有另一个与chrome相关的问题

有趣的是,有两个xslt文档,其中一个通过application/xslt+xml传输并被chrome接受,但另一个仅作为text/xml或text/xsl。是的,这两个文档都被chrome接受,我试过了

因此,对于这个问题,一个简单的解决方案可能没有用处

以下是控制台消息的详细信息:

服务器的调整已通过以下行完成,如果请求的文件名具有后缀xslt且预期mime类型为text/css,则会更改内容类型mime类型:

火狐

可能值得注意的是,firefox将util.xslt完全隐藏在网络面板中:

此外,Firefox接受ActiveXObject和XSLTProcessor这两种方法。根据JavaScript中的逻辑,默认设置为ActiveXObject,该版本在下拉菜单的动画方面看起来也更平滑

当xml版本设置为1.1时,Firefox会抱怨,因此会使用 版本号可能不会真正帮助提高浏览器兼容性。

我找到了解决此问题的方法[1]

在chrome中,在Javascript中转换时可以正常工作。因此,我将XML转换为XSL,并为每个下拉标记使用

更新util.xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"></xsl:output>
    <xsl:template name="dropdown">
        <xsl:param name="listname"/>
        <xsl:param name="value"/>
        <select>
            <xsl:for-each select="document('foo/b.xml')/dropdowns/dropdown[@name=$listname]/option">
                <option>
                    <xsl:attribute name="value">
                        <xsl:value-of select="@value"/>
                    </xsl:attribute>
                    <xsl:value-of select="."/>
                </option>
            </xsl:for-each>
        </select>
    </xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="foo/b.xslt" />
<xsl:output method="html" />

<xsl:template name="dropdown">
    <xsl:param name="listname"/>
    <xsl:param name="value"/>
    <select>
        <xsl:call-template name="dropdowns">
            <xsl:with-param name="listname" select="$listname"/>
            <xsl:with-param name="value" select="$value"/>
        </xsl:call-template>
    </select>
</xsl:template>
</xsl:stylesheet>

一,。我同意这不是一个很好的解决办法,当然也不是一个普遍的解决办法。如果有人有更好的解决方案,请将其作为答案发布。

这是一个已知的问题,自2009年开始开放。此外,Chrome团队甚至没有任何计划来修复它,他们正在计划从Chrome中删除它的支持,但不知道什么时候。但这个问题有一个解决办法。将xml数据转换为xslt,然后将其导入样式表

因此,您的javaScript代码将保持不变

foo/b.xml将成为foo/b.xslt

 <?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template name="dropdowns">
    <xsl:param name="listname"/>
    <xsl:param name="value"/>
    <xsl:choose>
        <xsl:when test="$listname='xyz'">
            <xsl:call-template name="option">
                <xsl:with-param name="value">I</xsl:with-param>
                <xsl:with-param name="label">Info</xsl:with-param>
                <xsl:with-param name="selectedValue" select="$value"/>
            </xsl:call-template>
            <xsl:call-template name="option">
                <xsl:with-param name="value">C</xsl:with-param>
                <xsl:with-param name="label">Category</xsl:with-param>
                <xsl:with-param name="selectedValue" select="$value"/>
            </xsl:call-template>
        </xsl:when>

    </xsl:choose>
 </xsl:template>

 <xsl:template name="option">
    <xsl:param name="label"/>
    <xsl:param name="value"/>
    <xsl:param name="selectedValue"/>
    <option value="{$value}">
        <xsl:if test="$value = $selectedValue">
            <xsl:attribute name="selected">selected</xsl:attribute>
        </xsl:if>
        <xsl:value-of select="$label"/>
    </option>
</xsl:template>
</xsl:stylesheet>
util.xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"></xsl:output>
    <xsl:template name="dropdown">
        <xsl:param name="listname"/>
        <xsl:param name="value"/>
        <select>
            <xsl:for-each select="document('foo/b.xml')/dropdowns/dropdown[@name=$listname]/option">
                <option>
                    <xsl:attribute name="value">
                        <xsl:value-of select="@value"/>
                    </xsl:attribute>
                    <xsl:value-of select="."/>
                </option>
            </xsl:for-each>
        </select>
    </xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="foo/b.xslt" />
<xsl:output method="html" />

<xsl:template name="dropdown">
    <xsl:param name="listname"/>
    <xsl:param name="value"/>
    <select>
        <xsl:call-template name="dropdowns">
            <xsl:with-param name="listname" select="$listname"/>
            <xsl:with-param name="value" select="$value"/>
        </xsl:call-template>
    </select>
</xsl:template>
</xsl:stylesheet>
render.xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:import href="util.xslt" />
    <xsl:output method="html"></xsl:output>
    <xsl:template match="/">
        <h1>
            <xsl:value-of select="/catalog/@name"></xsl:value-of>
        </h1>
        <xsl:call-template name="dropdown">
            <xsl:with-param name="listname">xyz</xsl:with-param>
            <xsl:with-param name="value" select="/catalog/@name"/>
        </xsl:call-template>
    </xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="util.xslt" />
<xsl:output method="html"></xsl:output>
<xsl:template match="/">
    <h1>
        <xsl:value-of select="/catalog/@name"></xsl:value-of>
    </h1>
    <xsl:call-template name="dropdown">
        <xsl:with-param name="listname">xyz</xsl:with-param>
        <xsl:with-param name="value">C</xsl:with-param>
    </xsl:call-template>
</xsl:template>
</xsl:stylesheet>

通过这些更改,您可以在页面中创建下拉列表,在IE和chrome中都可以使用。

您可以尝试为文档提供一个绝对URI参数,或者使用xml:base设置上下文URI吗?如果它能正常工作,那么URI的组成很可能会出错。控制台是否给出错误消息?我尝试使用绝对URL,但仍然不起作用。控制台为render.xslt和util.xslt提供解释为样式表但使用MIME类型application/xslt+xml:传输的资源。这是问题的原因吗?我不知道。根据预期,内容类型应该是text/xsl,因此您可以尝试告诉您的Web服务器使用它来交付.xsl文件,尽管我怀疑它是否会help@imhotap-可以在任何地方将其设置为text/xsl吗?Chrome的安全策略似乎不允许导入或文档引用。不,好的,Chrome不支持。无法导入xml文件,因为文档函数没有完成它的工作。