0

我正在尝试从 XSLT 脚本输出以下行。它是紧随其后的第一行xsl:template match="/"。我要做的是将 XML 文档转换为 XML 模式,并且需要以xs:schema特定方式输出标签。

<xs:schema xmlns:ed="http://test1"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" targetNamespace="{$ns_name}" xmlns:tns="{$ns_name}" elementFormDefault="qualified" attributeFormDefault="unqualified" xsi:schemaLocation="http://test1 file://XmlSchemaAppinfo.xsd">

$ns_name一个xsl:param name="ns_name"。它被正确解析,targetNamespace="{$ns_name}"但在xmlns:tns="{$ns_name}"字面上输出

<xs:schema targetNamespace="akolodk" elementFormDefault="qualified" attributeFormDefault="unqualified" xsi:schemaLocation="http://test1 file://XmlSchemaAppinfo.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ed="test1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="{$ns_name}">
4

2 回答 2

0

在 XSL 中,只有一些属性可以使用属性值模板(使用 '{}' 符号)来编写。特别是,xmlns 属性不支持该表示法。

于 2013-03-29T09:27:55.917 回答
0

命名空间声明与属性不同,即使它们看起来相同。在xmlns:tns样式表被解析时,XML 解析器在它到达 XSLT 处理器之前已经对它进行了处理。

如果您有 XSLT 2.0,您可以使用

<xsl:namespace name="tns" select="$ns_name"/>

在结果树中创建命名空间节点,但我知道没有简单的方法可以在 XSLT 1.0 中生成动态命名空间。你不能使用xsl:attribute,规范明确指出,虽然

<xsl:attribute name="xmlns:xsl" namespace="whatever">http://www.w3.org/1999/XSL/Transform</xsl:attribute>

不是错误,它将生成一个属性,而不是命名空间声明 - 处理器需要忽略 中xmlns指定的前缀,name并且必须使用不同的前缀来输出属性。

如果您的处理器支持 exsltnode-set扩展功能,那么以下可能会起作用:

<xsd:schema .....>
  <xsl:variable name="tnsElement">
    <xsl:element name="tns:dummy" namespace="{$ns_name}"/>
  </xsl:variable>
  <xsl:copy-of select="exsl:node-set($tnsElement)/*/namespace::tns"/>

但是再次允许处理器忽略xsl:element name属性的前缀并使用绑定到同一 URI 的不同前缀,您必须使用处理器对其进行测试。

(并且您必须添加xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl"到您的xsl:stylesheet元素中)。

于 2013-03-29T09:59:28.397 回答