Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
460 views
in Technique[技术] by (71.8m points)

xml - Select all nodes under one node and add prefix using XSLT

I Am trying to write an XSLT code to add sob prefix namespaces to all nodes(child and sibling) of mes:caseInfos

I want to add sob prefix to all child elements of mes:caseInfos as follow

<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:mes="namespace/service/servicename/messages/v1"
xmlns:cme="namespace/type/common/messages/v1"
xmlns:sob="namespace/type/servicename/types/mes"
xmlns:exc="namespace/type/common/exceptions/v1">
        <soapenv:Body>
            <mes:getCaseInfosResponse>
                <mes:messageContext>
                    <cme:timestamp>2021-01-27T15</cme:timestamp>
                </mes:messageContext>
                <mes:responses>
                    <mes:response>
                        <mes:caseInfos>
                            <instance>
                                <instanceId>AC_WSPmockedInstanceId</instanceId>
                            </instance>
                            <case>
                                <id>AC_WSPmockedId</id>
                                <caseTexts>
                                    <type>AC_WSPmockedType1</type>
                                </caseTexts>
                                <caseTexts>
                                    <type>AC_WSPmockedType2</type>
                                </caseTexts>
                                <decision>
                                    <code>AC_WSPmockedCode</code>
                                    <labelFr>AC_WSPmockedLabelFr</labelFr>
                                </decision>
                                <extracts>
                                    <extractFrStatus>AC_WSPmockedExtractFrStatus</extractFrStatus>
                                </extracts>
                            </case>
                        </mes:caseInfos>
                    </mes:response>
                </mes:responses>
            </mes:getCaseInfosResponse>
        </soapenv:Body>
    </soapenv:Envelope>

I came up with this XSLT, I tried this (and many others changing XPath..)

 <?xml version="1.0" encoding="UTF-8"?>
   <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:mes="namespace/service/servicename/messages/v1"
    xmlns:cme="namespace/type/common/messages/v1" xmlns:sob="namespace/type/servicename/types/v1"
    version="1.0">
        <xsl:output omit-xml-declaration="yes" />
        <!-- Copies all the nodes as is -->
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()" />
            </xsl:copy>
        </xsl:template>
    
        <!-- Select the element need to be apply the prefix -->
            <xsl:template match="//mes:response/descendant-or-self::caseInfos">
            <!--Define the namespace with prefix ns0 -->
            <xsl:element name="sob:{name()}" >
                <!--apply to above selected node -->
                <xsl:apply-templates select="node()|@*">
                </xsl:apply-templates>
            </xsl:element>
        </xsl:template>
    
    </xsl:stylesheet>

Expected Transformation

    <soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:mes="namespace/service/servicename/messages/v1"
xmlns:cme="namespace/type/common/messages/v1"
xmlns:sob="namespace/type/servicename/types/mes"
xmlns:exc="namespace/type/common/exceptions/v1">
    <soapenv:Body>
        <mes:getCaseInfosResponse>
            <mes:messageContext>
                <cme:messageId >4c22aa14-e54f-413a-93f5-26b96434d22e</cme:messageId>
                
            </mes:messageContext>
            <mes:responses>
                <mes:response>
                    <mes:caseInfos>
                        <sob:instance>
                            <sob:instanceId>AC_WSPmockedInstanceId</sob:instanceId>
                        </instance>
                        <sob:case>
                            <sob:id>AC_WSPmockedId</sob:id>
                            <sob:caseTexts>
                                <sob:type>AC_WSPmockedType1</sob:type>
                            </sob:caseTexts>
                            <sob:caseTexts>
                                <sob:type>AC_WSPmockedType2</sob:type>
                            </sob:caseTexts>
                            <sob:decision>
                                <sob:code>AC_WSPmockedCode</sob:code>
                            </sob:decision>
                            <sob:extracts>
                                <sob:extractFrStatus>AC_WSPmockedExtractFrStatus</sob:extractFrStatus>
                            </sob:extracts>
                        </case>
                    </mes:caseInfos>
                </mes:response>
            </mes:responses>
        </mes:getCaseInfosResponse>
    </soapenv:Body>
</soapenv:Envelope>

Any help would be greatly appreciated! :) Soukaina

question from:https://stackoverflow.com/questions/65934639/select-all-nodes-under-one-node-and-add-prefix-using-xslt

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The shortest form would

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:sob="namespace/type/servicename/types/mes"
    version="1.0">

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

  <xsl:template match="mes:caseInfos//*" xmlns:mes="namespace/service/servicename/messages/v1">
      <xsl:element name="sob:{local-name()}">
          <xsl:apply-templates select="@* | node()"/>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...