1

I am trying to update all <type> values to lower case which is working fine now. Also i wanted to change the namespace from v2.0 to v1.0 and it worked fine except that i don't want namespace to be declared for subelements like "category" and "authList" below. and most important thing i wanted to do is replace <Name> element with <Number> along with new numeric value to it. So 2 outstanding things i am trying to acheive here are: 1. Update the 'Name' element to 'Number' with new numeric value. (MUST for me) 2. If possible remove Namespaces from 'Category' or other subelements in the document except for the root element. (IF POSSIBLE)

Please let me know what is wrong with my XSLT. Thanks a lot. I hope i was able to keep the question simple.

XML Input:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
  <ns6:QueryResponse version="2.0" xmlns="" xmlns:ns6="http://www.abc.com/s/v2.0">
     <category>
        <categoryList>
           <cat>
              <type>SUPER</type>
              <value>gg44</value>
           </cat>
           <cat>
              <type>SUPER2</type>
              <value>fff</value>
           </cat>
        </categoryList>
     </category>
     <AuthList>
        <sAuthority>
           <Name>P</Name>
    </sAuthority>               
<AuthList>               
 </ns6:QueryResponse>
 </soapenv:Body>
 </soapenv:Envelope>

XML output -

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
  <v1:QueryResponse version="1.0" xmlns:v1="http://www.abc.com/s/v1.0">
     <category xmlns:ns2="http://www.abc.com/s/v1.0" xmlns:ns3="http://www.abc.com/s/v2.0">
        <categoryList>
           <cat>
              <type>super</type>
              <value>gg44</value>
           </cat>
           <cat>
              <type>super2</type>
              <value>fff</value>
           </cat>
        </categoryList>
     </category>
     <AuthList xmlns:ns2="http://www.abc.com/s/v1.0"  xmlns:ns3="http://www.abc.com/s/v2.0">
        <sAuthority>
           <Name>P</Name>
    </sAuthority>               
<AuthList>               
 </v1:QueryResponse>
 </soapenv:Body>
 </soapenv:Envelope>

XSLT code:

<?xml version="1.0" encoding="utf-8"?>
   <xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:old="http://www.abc.com/s/v2.0"
exclude-result-prefixes="old"
xmlns:v1="http://www.abc.com/s/v1.0">
<xsl:output method="xml" encoding="utf-8" indent="yes"
   version="1.0" />

<!-- Some parameters declered -->
<xsl:param name="newversion" select="'1.0'" />   
<xsl:param name="P_1" select="'1'" />
<xsl:param name="C_2" select="'2'" />
<xsl:param name="S_3" select="'3'" />
<xsl:param name="F_4" select="'4'" />   

<!-- This is to update namespace from v2.0 to v1.0 -->
<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
</xsl:template>

<xsl:template match="old:*">
    <xsl:element name="v1:{local-name()}">
        <xsl:apply-templates select="@* | node()" />
    </xsl:element>
</xsl:template>

<xsl:template match="old:QueryResponse/@version">
    <xsl:attribute name="version"> 
    <xsl:value-of select="$newversion" /> 
    </xsl:attribute>
</xsl:template>

<!-- This is to update the Name to Number -->
<xsl:template match="sAuthority/Name">
  <xsl:choose>
   <xsl:when test=".='P'">
       <xsl:element name="Number">
       <xsl:value-of select="$P_1"/>           
       </xsl:element>
   </xsl:when>
   <xsl:when test=".='C'">
       <xsl:element name="Number">
       <xsl:value-of select="$C_2"/>
       </xsl:element>                      
   </xsl:when>       
   <xsl:when test=".='S'">
       <xsl:element name="Number">
       <xsl:value-of select="$S_3"/>
       </xsl:element>          
   </xsl:when>  
   <xsl:when test=".='F'">
       <xsl:element name="Number">
       <xsl:value-of select="$F_4"/>
       </xsl:element>      
   </xsl:when>                   
  </xsl:choose>
  </xsl:template>  

 <!-- This is to update Upper case values to lower case for all the type elements in  the XML input whereever they are in the XML -->
 <xsl:template match="type/text()">
   <xsl:value-of
       select="translate (., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')" />
  </xsl:template>

  </xsl:stylesheet>

EXpected Output:-

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
  <v1:QueryResponse version="1.0" xmlns:v1="http://www.abc.com/s/v1.0">
     <category>
        <categoryList>
           <cat>
              <type>super</type>
              <value>gg44</value>
           </cat>
           <cat>
              <type>super2</type>
              <value>fff</value>
           </cat>
        </categoryList>
     </category>
     <AuthList>
        <sAuthority>
           <Number>1</Number>
    </sAuthority>               
<AuthList>               
 </v1:QueryResponse>
 </soapenv:Body>
 </soapenv:Envelope>

Thanks,

4

1 回答 1

1

如果您希望从categoryauthlist元素中删除名称空间声明,请尝试将此附加模板添加到您的 XSLT

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

这是有效的,因为xsl:copy将从您的输入 XML 中复制任何命名空间声明(无论它们是否被使用),因此您可以创建新元素而不是复制元素,新元素不会有声明。

从将Name更改为Number,您的 XSLT 看起来已经正确执行此操作。但是,我建议您考虑编写一系列模板,而不是使用xsl:choose ,如下所示:

<xsl:template match="sAuthority/Name">
  <number>
    <xsl:apply-templates />
  </number>
</xsl:template>

<xsl:template match="Name/text()[.='P']">
  <xsl:value-of select="$P_1"/>
</xsl:template>

<xsl:template match="Name/text()[.='C']">
  <xsl:value-of select="$C_2"/>
</xsl:template>

<xsl:template match="Name/text()[.='S']">
  <xsl:value-of select="$S_3"/>
</xsl:template>

<xsl:template match="Name/text()[.='F']">
  <xsl:value-of select="$F_4"/>
</xsl:template>
于 2013-09-22T15:17:06.297 回答