Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 添加新命名空间非根节点xslt 1.0_Xml_Xslt_Xslt 1.0 - Fatal编程技术网

Xml 添加新命名空间非根节点xslt 1.0

Xml 添加新命名空间非根节点xslt 1.0,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我看到了那个帖子 @StuartLC答案在根中起作用。我需要帮助。。。?如何向非根节点添加新名称空间 输入XML文档(是的,很恐怖,但它来自客户端) 232019324 28-08-2019 09:12:32 检察官办公室 260 我想得到: <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

我看到了那个帖子

@StuartLC答案在根中起作用。我需要帮助。。。?如何向非根节点添加新名称空间

输入XML文档(是的,很恐怖,但它来自客户端)


232019324
28-08-2019 09:12:32
检察官办公室
260
我想得到:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header/>
    <S:Body xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
        <ns3:Response xmlns:ns1="ttn/xml" xmlns="ttn/xml" xmlns:ns2="rtm/xml" xmlns:ns3="ws/xml">
            <record>
                <ns1:registryID>
                    <ns1:registryNumber>232019324</ns1:registryNumber>
                </ns1:registryID>
                <ns2:Date>28-08-2019 09:12:32</ns2:Date>
                <ns2:registry>
                    <ns2:type>otp</ns2:type>
                    <ns1:sender>
                        <ns1:ID>260</ns1:ID>
                    </ns1:sender>
                </ns2:registry>
            </record>
        </ns3:Response>
    </S:Body>
</soapenv:Envelope>

232019324
28-08-2019 09:12:32
检察官办公室
260
我需要添加/删除一些前缀节点。例如节点
->
或节点
->
或节点
->
。。。。xml输入的节点更多,但我只放了几个

我需要在节点响应中包含ns1,因为当我导入到SAP PO时,它会显示“未声明ns1”。我想我在节点上添加了前缀ns1,但我不知道。我在测试SAP中手动尝试将ns1包括在节点中并使用它。在其他xslt转换之后,我只需要映射所有xml的节点响应

这是我使用的xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns="ttn/xml" xmlns:ns2="rtm/xml" xmlns:ns3="ws/xml"     xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
            xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

<xsl:output omit-xml-declaration="yes" method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:variable name ="mynoderecord">record</xsl:variable>
<xsl:variable name ="mynodeResponse">Response</xsl:variable> 
<xsl:variable name ="mynoderegistryNumber">registryNumber</xsl:variable>
<xsl:variable name ="mynodeRegistryID">registryID</xsl:variable>
<xsl:variable name ="mynodesender">sender</xsl:variable>


  <xsl:template match="*" >
  <xsl:choose>

    <xsl:when test="local-name() = $mynodeResponse">
     <xsl:element name="ns3:{local-name()}" xmlns:ns3="ws/xml">
    <xsl:attribute name="ns1:nsdf" namespace="ttn/xml">sdf</xsl:attribute>

       <xsl:for-each select="@*">
           <xsl:attribute name="{local-name()}">
           <xsl:value-of select="."/>
         </xsl:attribute>
       </xsl:for-each>
      <xsl:apply-templates/>
     </xsl:element>
    </xsl:when>


    <xsl:when test="local-name() = $mynoderegistryNumber" >
     <xsl:element name="ns1:{name()}" xmlns:ns1="ttn/xml">
       <!-- procesar atributos de nodo -->
       <xsl:for-each select="@*">
       <!-- eliminar prefijo de atributo -->
         <xsl:attribute name="{local-name()}">
           <xsl:value-of select="."/>
         </xsl:attribute>
       </xsl:for-each>
      <xsl:apply-templates/>
     </xsl:element>
    </xsl:when>

    <xsl:when test="local-name() = $mynodesender" >
     <xsl:element name="ns1:{name()}" xmlns:ns1="ttn/xml">
       <!-- procesar atributos de nodo -->
       <xsl:for-each select="@*">
       <!-- eliminar prefijo de atributo -->
         <xsl:attribute name="{local-name()}">
           <xsl:value-of select="."/>
         </xsl:attribute>
       </xsl:for-each>
      <xsl:apply-templates/>
     </xsl:element>
    </xsl:when>

    <xsl:when test="local-name() = $mynodeRegistryID" >
     <xsl:element name="ns1:{name()}" xmlns:ns1="ttn/xml">
       <!-- procesar atributos de nodo -->
       <xsl:for-each select="@*">
       <!-- eliminar prefijo de atributo -->
         <xsl:attribute name="{local-name()}">
           <xsl:value-of select="."/>
         </xsl:attribute>
       </xsl:for-each>
      <xsl:apply-templates/>
     </xsl:element>
    </xsl:when>

    <xsl:when test="local-name() = $mynoderecord">
     <xsl:element name="{local-name()}" xmlns:ns3="ws/xml">
       <!-- procesar atributos de nodo -->
       <xsl:for-each select="@*">
       <!-- eliminar prefijo de atributo -->
         <xsl:attribute name="{local-name()}">
           <xsl:value-of select="."/>
         </xsl:attribute>
       </xsl:for-each>
      <xsl:apply-templates/>
     </xsl:element>
    </xsl:when>


    <xsl:otherwise>
     <xsl:element name="{name()}">
       <!-- procesar atributos de nodo -->
       <xsl:for-each select="@*">
       <!-- eliminar prefijo de atributo -->
         <xsl:attribute name="{local-name()}">
           <xsl:value-of select="."/>
         </xsl:attribute>
       </xsl:for-each>
      <xsl:apply-templates/>
     </xsl:element>
     </xsl:otherwise>

  </xsl:choose>

  </xsl:template>

</xsl:stylesheet>

记录
回应
注册号
登记的
发件人
自卫队
搜索时,我看到将属性添加到节点
,命名空间ns1会自动添加。。。但是我不喜欢。 当然,有一个简单的解决方案和更好的代码。。。 xsl会让我发疯的

我试过了,但找不到更容易的合适的解决办法

你能给我提个建议吗

谢谢

您需要区分“添加名称空间节点”和“更改元素的扩展名称”

对于Response元素,您正在添加名称空间节点,而不更改任何元素或属性的名称。在XSLT2.0中,可以使用
xsl:namespace
指令来实现这一点。在XSLT 1.0中,只能通过一种相当复杂的解决方法来完成:在新名称空间中创建一个虚拟元素,然后复制其名称空间节点:

<xsl:variable name="dummy">
  <ns1:dummy xmlns:ns1="ttn/xml"/>
</xsl:variable>
<xsl:copy-of select="exsl:node-set($dummy)//namespace::*"/>


对于
registryID
元素,实际上您正在更改元素的扩展名称,为了实现这一点,通常需要使用
,这可能返回也可能不返回您期望得到的确切结果,这取决于XSLT处理者的突发奇想:

XSLT1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="ttn/xml"
xmlns:ns3="ws/xml">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="ns3:Response">
     <ns3:Response xmlns:ns1="ttn/xml" xmlns="ttn/xml" xmlns:ns2="rtm/xml" xmlns:ns3="ws/xml">
        <xsl:apply-templates/>
    </ns3:Response>
</xsl:template>

<xsl:template match="ns3:record">
    <record xmlns="ttn/xml">
        <xsl:apply-templates/>
    </record>
</xsl:template>

<xsl:template match="ns1:*">
    <xsl:element name="ns1:{local-name()}">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>



注意,只有第三个模板做了实质性的工作:它将
ns3:record
移动到不同的名称空间。其他模板是纯粹的化妆品,不应该是必需的。

您显示的结果没有什么意义:
记录
位于
“ttn/xml”
命名空间中(继承自父
ns3:Response
上的默认命名空间声明)
ns1:registryID
也在相同的
“ttn/xml”
命名空间中,因为这是绑定到
ns1
前缀的命名空间。为什么在一个节点上使用前缀而在另一个节点上不使用前缀(反之亦然)?@michael.hor257k是的,但我必须在节点上添加前缀has not prefix。。。默认名称空间ttn/xml中的所有节点都将绑定到ns1(我不太理解),那么为什么不将
record
设为
ns1:record
注意,前缀不应该很重要。同样,名称空间声明的位置也是如此。重要的是节点位于正确的命名空间中。如果您处理的解析器依赖于这两者中的任何一个,那么无论您做什么,您都将面临不可预测的结果。@michael.hor257k是的,我同意您的看法。。。但是客户端的响应是,记录元素eg有前缀,我必须删除它,其他我必须添加eg registryID。。。因为我必须以这种结构导入SAP。对不起,我应该将代码放在代码中的什么位置?out或Response元素?好吧,我会完全重新构造您的代码,使用模板规则而不是一个大的xsl:choose,并使用文本结果元素而不是xsl:element,而且我不会尝试生成不必要的名称空间;但是,如果您希望在响应元素上有一个额外的名称空间(您似乎希望这样),那么这就是放置它的位置。我试图在代码中包含响应元素,但名称空间没有出现。我建议开始一个新问题,以显示您的代码、预期输出和实际输出。正是!!但是,如果registryID元素没有前缀,您可以解释第四个模板吗?如何找到模板匹配=“ns1:*?”O@Blas模板不查找前缀为
ns1
的元素。它查找绑定到XSLT样式表顶层命名空间声明中
ns1
前缀的命名空间中的元素。如果您的问题得到了回答,请通过接受答案来结束它。它可以工作,但当我导入到SAP时,我看到“缺少记录元素”并且不工作。确实是名称空间问题:(当您尝试导入转换结果时是否会发生这种情况?如果是,则问题在于您的预期结果。
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="ttn/xml"
xmlns:ns3="ws/xml">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="ns3:Response">
     <ns3:Response xmlns:ns1="ttn/xml" xmlns="ttn/xml" xmlns:ns2="rtm/xml" xmlns:ns3="ws/xml">
        <xsl:apply-templates/>
    </ns3:Response>
</xsl:template>

<xsl:template match="ns3:record">
    <record xmlns="ttn/xml">
        <xsl:apply-templates/>
    </record>
</xsl:template>

<xsl:template match="ns1:*">
    <xsl:element name="ns1:{local-name()}">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>