【问题标题】:Adding namespace to child elements using xslt使用 xslt 向子元素添加命名空间
【发布时间】:2010-08-26 10:29:33
【问题描述】:

下面是输入的xml:

<ns:TXLife xmlns:ns="http://ACORD.org/Standards/Life/2">

  <TXLifeResponse>
     <TransRefGUID/>
     <TransExeDate/>
     <TransExeTime/>

     <TransType tc="228"/>

</ns:TXLife>

以下是我的 XSLT:

xmlns:ns="http://ACORD.org/Standards/Life/2" version="1.0">

<xsl:output omit-xml-declaration="yes" indent="yes"/>    

<xsl:template match="/">

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:acor="http://www.foresters.com/esb/ws/wsdl/ACORD-v1.0" xmlns:ns="http://ACORD.org/Standards/Life/2">

       <soapenv:Header/>

        <soapenv:Body>

    <xsl:copy>
        <xsl:apply-templates />
    </xsl:copy>

           </soapenv:Body>
        </soapenv:Envelope>

</xsl:template>

<xsl:template match="node() [local-name(.) = 'TXLife']">

    <xsl:element name="ns:{local-name()}">

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

       </xsl:element>

  </xsl:template>

通过使用此转换,我无法将命名空间前缀添加到 TXLife 的所有子元素。

如何为所有子元素添加命名空间前缀(ns)?所以它应该如下所示

  <ns:TXLifeResponse>
     <ns:TransRefGUID/>
     <ns:TransExeDate/>
     <ns:TransExeTime/>

     <ns:TransType tc="228"/>

</ns:TXLife>

【问题讨论】:

    标签: xslt


    【解决方案1】:

    如果您希望 TXLife 和后代位于http://ACORD.org/Standards/Life/2 命名空间下,请使用此样式表:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ns="http://ACORD.org/Standards/Life/2"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <xsl:template match="/">
            <soapenv:Envelope>
                <soapenv:Header/>
                <soapenv:Body>
                    <xsl:apply-templates/>
                </soapenv:Body>
            </soapenv:Envelope>
        </xsl:template>
        <xsl:template match="*[ancestor-or-self::ns:TXLife]">
            <xsl:element name="ns:{local-name()}">
                <xsl:apply-templates select="@*|node()"/>
            </xsl:element>
        </xsl:template>
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    

    输出:

    <soapenv:Envelope
     xmlns:ns="http://ACORD.org/Standards/Life/2"
      xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <soapenv:Header />
        <soapenv:Body>
            <ns:TXLife>
                <ns:TXLifeResponse>
                    <ns:TransRefGUID></ns:TransRefGUID>
                    <ns:TransExeDate></ns:TransExeDate>
                    <ns:TransExeTime></ns:TransExeTime>
                    <ns:TransType tc="228"></ns:TransType>
                </ns:TXLifeResponse>
            </ns:TXLife>
        </soapenv:Body>
    </soapenv:Envelope>
    

    【讨论】:

      【解决方案2】:

      您的 XML 无效,但我假设您错过了结束 TXLifeResponse 元素。

      下面的转换会做你想做的事:

      XML:

      <?xml version="1.0" encoding="UTF-8"?>
      <ns:TXLife xmlns:ns="http://ACORD.org/Standards/Life/2">
      
        <TXLifeResponse>
          <TransRefGUID/>
          <TransExeDate/>
          <TransExeTime/>
      
          <TransType tc="228"/>
        </TXLifeResponse>
      
      </ns:TXLife>
      

      XSLT:

      <?xml version="1.0" encoding="UTF-8"?>
      <xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
        xmlns:ns="http://ACORD.org/Standards/Life/2">
      
        <xsl:output omit-xml-declaration="yes" indent="yes"/>
      
        <xsl:template match="/">
          <soapenv:Envelope 
            xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
            xmlns:acor="http://www.foresters.com/esb/ws/wsdl/ACORD-v1.0" 
            xmlns:ns="http://ACORD.org/Standards/Life/2">
            <soapenv:Header/>
            <soapenv:Body>
              <xsl:copy>
                <xsl:apply-templates/>
              </xsl:copy>
            </soapenv:Body>
          </soapenv:Envelope>
        </xsl:template>
      
        <xsl:template match="*">
          <xsl:element name="ns:{local-name()}">
            <xsl:apply-templates select="@*|node()"/>
          </xsl:element>
        </xsl:template>
      
        <xsl:template match="@*">
          <xsl:copy-of select="."/>
        </xsl:template>
      
      </xsl:stylesheet>
      

      输出:

      <soapenv:Envelope 
        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
        xmlns:acor="http://www.foresters.com/esb/ws/wsdl/ACORD-v1.0" 
        xmlns:ns="http://ACORD.org/Standards/Life/2">
        <soapenv:Header/>
        <soapenv:Body>
          <ns:TXLife>
            <ns:TXLifeResponse>
              <ns:TransRefGUID/>
              <ns:TransExeDate/>
              <ns:TransExeTime/>
              <ns:TransType tc="228"/>
            </ns:TXLifeResponse>
          </ns:TXLife>
        </soapenv:Body>
      </soapenv:Envelope>
      

      模板xsl:template match="node()[local-name(.) = 'TXLife']" 对我来说有点奇怪。你想达到什么目的?也许我们可以帮助解释为什么这不是合适的方法。

      【讨论】:

      • 因为我正在为特定节点“TXLife”做事。这样它的所有子元素都应该以'ns'为前缀
      • @Madhu CM:我理解你的意图,但是匹配模板只会匹配你源文档中的一个节点,本地名称为TXLife的节点,其余的将由内置的模板规则处理.如果这解决了您的问题,请将我的答案标记为解决方案! ;)
      猜你喜欢
      • 2012-08-16
      • 1970-01-01
      • 2011-02-10
      • 1970-01-01
      • 2014-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-04
      相关资源
      最近更新 更多