固有命名空间 XSLT 问题

Trouble with inherent namespace XSLT

提问人:Даріна Толстих 提问时间:9/7/2022 更新时间:9/7/2022 访问量:42

问:

我在命名空间方面有问题。我需要这个输出:

<xyt:arguments xmlns:xyt="urn:xytechsystems.com/XytechAPI"
            xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas">

但是在将此命名空间 xmlns:xyt=“urn:xytechsystems.com/XytechAPI” 添加到我尝试使用 xsl:namesapce 的参数时遇到问题,但认为使用节点继承有问题 我的 XSLT:

?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:amc="http://schemahost.amcnetworks.com:8080/amcnesb/schemas/adam"
    xmlns:my="http://tempuri.org/dummy"
    xmlns:i ="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas" exclude-result-prefixes="#all"
    version="3.0">
    <xsl:output method="xml" encoding="UTF-8" version="1.0" indent="yes"/>

     <xsl:element name="soapenv:Envelope" >
            <xsl:namespace name="i" select="'http://www.w3.org/2001/XMLSchema-instance'"/>
            <xsl:namespace name="xyt1"
                select="'http://schemas.datacontract.org/2004/07/Xytech.MP.API'"/>
            <xsl:namespace name="xyt" select="'urn:xytechsystems.com/XytechAPI'"/>
            <xsl:element name="soapenv:Header"/>
            <xsl:element name="soapenv:Body"/>
            <xsl:element name="xyt:Upsert">
                <xsl:element name="xyt:credentials">
                     </xsl:element>
                 <xsl:element name="xyt:arguments">
                   <xsl:namespace name="xyt" select="urn:xytechsystems.com/XytechAPI">
                   <xsl:namespace name="NS1"
                       select="'http://schemahost.amcnetworks.com:8080/amcnesb/schemas'"/>

                    

我的输出:

<soapenv:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
                  xmlns:xyt1="http://schemas.datacontract.org/2004/07/Xytech.MP.API"
                  xmlns:xyt="urn:xytechsystems.com/XytechAPI"
                  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body/>
   <xyt:Upsert>
      <xyt:credentials/>
           <xyt:arguments xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas">
        <xsl:namespace name="xyt" select="'urn:xytechsystems.com/XytechAPI'"/>
XSLT 命名空间 XSLT-3.0

评论

1赞 Mads Hansen 9/7/2022
命名空间已在祖先上声明,因此它将在范围内。您是否试图让它明确地显示在元素上?此外,在您的示例中,在尝试重新定义该命名空间时,您的@select中没有单引号中的命名空间,因此我希望它要么出错,要么不选择任何内容。xytsoapenv:Envelopexyt:argumentsxyt

答:

0赞 Martin Honnen 9/7/2022 #1

如果您希望 XSLT 输出一个元素,例如

<xyt:arguments xmlns:xyt="urn:xytechsystems.com/XytechAPI"
            xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas">

</xyt:arguments>

那么最简单和最直接的方法就是将其写成一个文字结果元素,即

<xyt:arguments xmlns:xyt="urn:xytechsystems.com/XytechAPI"
            xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas">

</xyt:arguments>

仅当要根据某些输入数据在执行 XSLT 期间计算名称和/或命名空间(或至少其中的一部分)时,才需要全部使用 of。xsl:element

评论

0赞 Даріна Толстих 9/7/2022
不幸的是,它没有用
2赞 Michael Kay 9/7/2022 #2

您已标记问题 xslt-1.0,但 xsl:namespace 是 XSLT 2.0 指令。

假设您正在创建其名称静态已知的元素,则使用文本结果元素最简单的方式是执行此操作。改变:

<xsl:element name="soapenv:Envelope" >
            <xsl:namespace name="i" select="'http://www.w3.org/2001/XMLSchema-instance'"/>
            <xsl:namespace name="xyt1"
                select="'http://schemas.datacontract.org/2004/07/Xytech.MP.API'"/>
            <xsl:namespace name="xyt" select="'urn:xytechsystems.com/XytechAPI'"/>
            <xsl:element name="soapenv:Header"/>
            <xsl:element name="soapenv:Body"/>
            <xsl:element name="xyt:Upsert">
                <xsl:element name="xyt:credentials">
                     </xsl:element>

<soapenv:Envelope 
   xmlns:i='http://www.w3.org/2001/XMLSchema-instance'
   xmlns:xyt1='http://schemas.datacontract.org/2004/07/Xytech.MP.API'
   xmlns:xyt='urn:xytechsystems.com/XytechAPI'>
   <soapenv:Header/>
   <soapenv:Body/>
   <xyt:Upsert>
     <xyt:credentials/>

任何必须阅读您的代码的人都会永远感激您。

0赞 al.truisme 9/7/2022 #3

我同意 @mads-hansen 的评论:

命名空间 URI 已在祖先元素中使用前缀声明,因此不会在相同前缀的子元素中重新声明。(这是 XSLT 中的命名空间修复机制。xyt

您可以将父前缀更改为 ,以便前缀在元素中是新的,即使它是相同的命名空间 URI。xyt1xytxyt:arguments

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas" 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xyt1="urn:xytechsystems.com/XytechAPI"
    exclude-result-prefixes="#all"
    version="3.0">
  
    <xsl:output method="xml" encoding="UTF-8" version="1.0" indent="yes"/>

    <xsl:template name="xsl:initial-template">
      <xsl:element name="soapenv:Envelope" >
        <xsl:element name="soapenv:Header"/>
        <xsl:element name="soapenv:Body"/>
        <xsl:element name="xyt1:Upsert">
          <xsl:element name="xyt1:credentials" />
          <xsl:element name="xyt:arguments" namespace="urn:xytechsystems.com/XytechAPI">
            <xsl:namespace name="NS1" select="'http://schemahost.amcnetworks.com:8080/amcnesb/schemas'"/>
          </xsl:element>
        </xsl:element>
      </xsl:element>
    </xsl:template>
  </xsl:stylesheet>

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xyt1="http://schemas.datacontract.org/2004/07/Xytech.MP.API">
   <soapenv:Header/>
   <soapenv:Body/>
   <xyt1:Upsert xmlns:xyt1="urn:xytechsystems.com/XytechAPI">
      <xyt1:credentials/>
      <xyt:arguments xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas" xmlns:xyt="urn:xytechsystems.com/XytechAPI"/>
   </xyt1:Upsert>
</soapenv:Envelope>

但我不明白为什么这比在文档中的任何地方使用相同的前缀更可取。xyt