使用xslt向元素和子节点添加名称空间前缀



我想复制只有头元素与所有子节点,并添加到每个子节点前缀"v11"(包括头元素)

源xml:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <ns3:createReservationRequest xmlns:ns3="ns3URL" xmlns:ns2="ns2URL">
            <header>
                <language isoCountryCode="US" isoLanguageCode="en"/>
                <channel name="DT">
                    <subChannel name="WEBWB">
                        <subChannel name="WEBWB">
                            <subChannel name="Functester">
                                <subChannel name="ecom"/>
                            </subChannel>
                        </subChannel>
                    </subChannel>
                </channel>
            </header>
            <ns3:agentInfo>
                <ns2:agentDutyCode>PR</ns2:agentDutyCode>
            </ns3:agentInfo>
        </ns3:createReservationRequest>
    </soap:Body>
</soap:Envelope>

期望结果xml:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
              xmlns:v1="v1URL"
              xmlns:v11="v11URL">
    <soapenv:Body>
        <v1:createBookerEventRequest>
            <v11:header>
                <v11:channel name="DT">
                    <v11:subChannel name="WEBWB">
                        <v11:subChannel name="WEBWB">
                            <v11:subChannel name="Functester">
                                <v11:subChannel name="ecom"/>
                            </v11:subChannel>
                        </v11:subChannel>
                    </v11:subChannel>
                </v11:channel>
            </v11:header>
        </v1:createBookerEventRequest>
    </soapenv:Body>
</soapenv:Envelope>

我试着从这里用例子来实现这个。我编写了以下xsl:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
            xmlns:v11="v11URL">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:template match="/">
        <xsl:copy>
            <xsl:apply-templates select="//*[local-name()='header']/*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="//*[local-name()='header']/*">
        <xsl:element name="v11:{name()}" inherit-namespaces="no">
            <xsl:apply-templates select="node()|@*"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

但是它不会将子通道复制到result xml中。并且还添加了不必要的"xmlns:v11="http://example.com/schema/common/ATPCommonServiceTypes/v1"属性到头子节点。

这是我的(编辑)建议:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
            xmlns:v1="v1URL"
            xmlns:v11="v11URL"
            xmlns:ns3="ns3URL"
            exclude-result-prefixes="soap ns3">
<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* , node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="/*">
  <xsl:copy>
    <xsl:copy-of select="document('')/xsl:stylesheet/namespace::*[local-name() = ('v1', 'v11')]"/>
    <xsl:apply-templates select="@* , node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="*[not(namespace-uri())]">
  <xsl:element name="v11:{local-name()}">
    <xsl:apply-templates select="@* , node()"/>
  </xsl:element>
</xsl:template>
<xsl:template match="ns3:createReservationRequest">
  <v1:createBookerEventRequest>
    <xsl:apply-templates select="@* , node()"/>
  </v1:createBookerEventRequest>
</xsl:template>
<xsl:template match="ns3:agentInfo"/>
</xsl:stylesheet>

我添加了一个xmlns声明到agentDutyCode,因为它缺少一个命名空间声明:

<ns2:agentDutyCode xmlns:ns2="ns2URL">PR</ns2:agentDutyCode>

使用这个样式表的源代码(模板在注释中解释):

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:v11="v11URL"
    xmlns:v1="v1URL"
    xmlns:ns3="ns3URL"
    exclude-result-prefixes="ns3">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>
    <!-- Copies Envelope and Body preserving their namespace -->
    <xsl:template match="soap:Envelope | soap:Body">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <!-- Creates the createReservationRequest element -->
    <xsl:template match="ns3:createReservationRequest">
        <v1:createBookerEventRequest>
            <xsl:apply-templates/>
        </v1:createBookerEventRequest>
    </xsl:template>
    <!-- Ignores language and agentInfo subtrees -->
    <xsl:template match="language"/>
    <xsl:template match="ns3:agentInfo"/>
    <!-- Matches all other elements -->
    <xsl:template match="*">
        <xsl:element name="v11:{local-name()}" inherit-namespaces="no">
            <xsl:apply-templates select="node()|@*"/>
        </xsl:element>
    </xsl:template>
    <!-- Copies attributes -->
    <xsl:template match="@*">
        <xsl:copy>
            <xsl:value-of select="."/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

你将得到这样的结果:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <v1:createBookerEventRequest xmlns:v11="v11URL" xmlns:v1="v1URL">
         <v11:header>
            <v11:channel name="DT">
               <v11:subChannel name="WEBWB">
                  <v11:subChannel name="WEBWB">
                     <v11:subChannel name="Functester">
                        <v11:subChannel name="ecom"/>
                     </v11:subChannel>
                  </v11:subChannel>
               </v11:subChannel>
            </v11:channel>
         </v11:header>
      </v1:createBookerEventRequest>
   </soap:Body>
</soap:Envelope>

下面是一个XSLT文件,您可以在其中看到结果。

相关内容

  • 没有找到相关文章

最新更新