使用xslt匹配和添加带动态命名空间的元素

时间:2014-02-13 22:33:08

标签: xslt

我有一些xml如下......

<ns1:service1 xmlns:ns1="http://foo.com/service_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:SystemInfo>
    <ns1:functionMode>Y</ns1:functionMode>
</ns1:SystemInfo>
</ns1:service>

现在我需要接受并做两件事

  1. 包装在SOAP信封中
  2. 在SystemInfo中插入反式标记
  3. 以下作品包装......

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output omit-xml-declaration="yes" indent="yes"/>
      <xsl:param name = "transId" />
    
      <xsl:template match="@*|node()">
         <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
         </xsl:copy>
      </xsl:template>
    
      <xsl:template match="*">
         <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
           <soapenv:Header/>
           <soapenv:Body>
             <xsl:copy-of select="/*"/>
           </soapenv:Body>
         </soapenv:Envelope>
      </xsl:template>
    
    </xsl:stylesheet>
    

    现在我需要添加标签,问题是我们不知道命名空间是什么(并且它可以根据请求进行更改)。所以我不能硬编码。但是,它已经存在于根标记中。

    所以我想要......

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
      <soapenv:Header/>
      <soapenv:Body>
        <ns1:service1 xmlns:ns1="http://foo.com/service_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ns1:SystemInfo>
             <ns1:trans />
         <ns1:functionMode>Y</ns1:functionMode>
      </ns1:SystemInfo>
        </ns1:service>
      </soapenv:Body>
    </soapenv:Envelope>
    

    但这似乎没有实现它......

    <xsl:template match="*[local-name()='SystemInfo']">
      <xsl:copy>
        <xsl:element name="type"/>
        <xsl:call-template name="copy-children"/>
      </xsl:copy>
    </xsl:template>
    
    <!-- Copy the children of the current node. -->
    <xsl:template name="copy-children">
      <xsl:copy-of select="./*"/>
    </xsl:template>
    

    上述应该是什么?

1 个答案:

答案 0 :(得分:3)

相反,如果使用 xsl:copy-of 而只是复制当前元素而不允许您进行任何更改,请使用 xsl:apply-templates

  <soapenv:Body>
    <xsl:apply-templates select="@*|node()"/>
  </soapenv:Body>

然后,您可以编写模板以匹配 SystemInfo 元素,并添加所需的任何新元素。您甚至可以使用 namespace-uri 函数将其添加到相同的命名空间。

<xsl:template match="*[local-name()='SystemInfo']">
   <xsl:copy>
     <xsl:element name="trans" namespace="{namespace-uri()}" />
     <xsl:apply-templates select="@*|node()"/>
   </xsl:copy>
</xsl:template>

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:param name="transId"/>

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

  <xsl:template match="/">
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
      <soapenv:Header/>
      <soapenv:Body>
        <xsl:apply-templates select="@*|node()"/>
      </soapenv:Body>
    </soapenv:Envelope>
  </xsl:template>

  <xsl:template match="*[local-name()='SystemInfo']">
     <xsl:copy>
       <xsl:element name="trans" namespace="{namespace-uri()}" />
       <xsl:apply-templates select="@*|node()"/>
     </xsl:copy>
  </xsl:template>
</xsl:stylesheet>