【问题标题】:xsl generate attribute with prefixxsl 生成带前缀的属性
【发布时间】:2014-12-09 01:50:30
【问题描述】:

我是 XSL 的新手,我的任务是生成带有 xmlns:A.B.C 前缀/值作为根节点属性的输出 xml。具体是这样的:

<GetVersionResponse xmlns:A.B.C="www.somesite.co.uk/A/B/C">
    <Class>GetVersionRequest</Class>
    <Errors>
        <Error>
            <Text>Some message</Text>
        </Error>
    </Errors>
</GetVersionResponse>

这是我的输入:

<Error>
    <Namespace>xmlns:A.B.C</Namespace>
    <NamespaceValue>www.somesite.com/A/B/C</NamespaceValue>
    <Class>GetVersionRequest</Class>
    <Message>Some message</Message>
</Error>

这是 Error.xsl 文件中重要的 sn-p:

<xsl:template match="Error">                    
    <xsl:variable name="ResponseType">
        <xsl:value-of select="concat(substring-before(Class, 'Request'),'Response')"/>
    </xsl:variable>        
    <xsl:variable name="NS">
        <xsl:value-of  select="Namespace"/>
    </xsl:variable>
    <xsl:variable name="NSV">
        <xsl:value-of  select="NamespaceValue"/>
    </xsl:variable>

    <xsl:element name="{$ResponseType}" namespace="{$NSV}" xml:space="default">
    ...
</xsl:template 

它会生成以下错误,因为我的输入的命名空间元素中有一个冒号:

XSLT 2.0 调试错误:未知的命名空间前缀

如果我用下划线替换冒号,我会得到我需要的确切输出,但当然只能用下划线。像这样:

<GetVersionResponse xmlns_A.B.C="www.somesite.co.uk/A/B/C">
    <Class>GetVersionRequest</Class>
    <Errors>
        <Error>
            <Text>Some message</Text>
        </Error>
    </Errors>
</GetVersionResponse>

我已经在网上搜索了几个小时,并认为我正在尝试将 xmlns: 作为文本插入,而不是使用将生成 xmlns:MYTEXT 但不知道如何操作的正确对象。

非常感谢您的帮助!!!!

【问题讨论】:

  • 但是添加一个在文档中任何地方都没有使用的命名空间声明有什么意义呢?
  • 这是应我们客户的要求,因此他们使用我们的网络服务的系统在根节点中包含一个标识符,无论他们有什么目的。
  • 是的,我知道这是某人的要求——但这不是命名空间声明的用途。 “包含在根节点中的标识符”如果将根节点(以及因此,整个文档)放置在给定的命名空间中,将是有意义的。但在这种情况下,前缀既不必要也没有意义。

标签: xslt namespaces prefix


【解决方案1】:

这里的复杂因素是,就 XPath 数据模型而言,xmlns:... 命名空间声明不是属性,因此您不能使用xsl:attribute 创建它们。但是,在 XSLT 2.0 中,您可以使用xsl:namespace 创建它们。

<xsl:template match="Error">
  <xsl:element name="{substring-before(Class, 'Request')}Response">
    <xsl:namespace name="{substring-after(Namespace, 'xmlns:')}"
                   select="NamespaceValue" />
    <xsl:copy-of select="Class" />
    <Errors>
      <Error>
        <Text><xsl:value-of select="Message" /></Text>
      </Error>
    </Errors>
  </xsl:element>
</xsl:template>

Live demo

xsl:namespacename 属性是您要绑定的前缀(所以 包括xmlns:),而select 给出了您要绑定到的URI。

【讨论】:

  • 这太棒了。非常感谢你这么快的回答,你在这里为我节省了很多时间!!!!
  • 嗨。我意识到我在使用 .Net 时受限于 XSL 1.0,并且不想添加像 Saxon 这样的第三方引用。因此我不能使用 xsl:namespace。目前我已经通过使用 xsl:choose 来检测输入类并返回特定元素来解决: 但它不是很通用,不会对新的输入类做出反应。有什么想法吗?
  • @DP-Dev 我不相信这可以在 XSLT 1.0 中完成。如果 DrugInformationResponse 元素是 in 所需的命名空间,那么这很容易:&lt;xsl:element name="{substring-after(Namespace, 'xmlns:')}:{substring-before(Class, 'Request')}Response" namespace="{NamespaceValue}"&gt; 将创建 &lt;HDS.CI.DIR:DrugInformationResponse xmlns:HDS.CI.DIR="..."&gt; - 但是动态创建 unused 命名空间绑定并不是什么事情XSLT 1.0 可以做到。它只能使用文字结果元素静态创建它们,或者通过复制在输入树中的另一个元素上声明的命名空间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-06
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多