简体   繁体   中英

Move an XML element from its place, to under another parent element using xslt

I'm trying to move the location of an xml element and have it wrap around all the other elements under the future parent.

Input:

<soap:Body>
  <pre:getResponse>
           <![CDATA[
               <pre:Request>
        .......
               </pre:Request>
    ]]>
</pre:getResponse>

Desired Output:

 <soap:Body>
  <pre:getResponse>
    <pre:Request>
       <![CDATA[

        .......

        ]]>
    </pre:Request>
</pre:getResponse>

See the snippet below. Here I added a cdata tag to the xml and it wrapped around the other elements just fine. I'd like to do something similar only this time, the tag is already in the xml:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:pre="
[Insert namespace]" version="1.0" >
<xsl:output method="xml" encoding="utf-8" indent="yes"/>

<xsl:template match="pre:Request">
  <xsl:copy>
    <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
    <xsl:copy-of select="*"/>    
    <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
  </xsl:copy>
</xsl:template>
</xsl:stylesheet>

As I mentioned in a comment to your question, there is no pre:Request element in your input XML snippet, so it cannot be "moved". The entire CDATA section is just a meaningless string, containing no markup.

You could try removing the unwanted portion by string manipulation:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:pre="http://example.com/pre">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" cdata-section-elements="pre:Request"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="pre:getResponse">
    <xsl:copy>
        <pre:Request>
            <xsl:value-of select="substring-before(substring-after(., '&lt;pre:Request>'), '&lt;/pre:Request>')"/>
        </pre:Request>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Given a well-formed input such as:

XML

<soap:Body xmlns:soap="http://www.w3.org/2003/05/soap-envelope/">
   <pre:getResponse xmlns:pre="http://example.com/pre">
      <![CDATA[
         <pre:Request>
            <payload>
               <item id="1">001</item>
               <item id="2">002</item>
               <item id="3">003</item>
            </payload>
         </pre:Request>
      ]]>
   </pre:getResponse>
</soap:Body>

the result will be:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Body xmlns:soap="http://www.w3.org/2003/05/soap-envelope/">
  <pre:getResponse xmlns:pre="http://example.com/pre">
    <pre:Request><![CDATA[
            <payload>
               <item id="1">001</item>
               <item id="2">002</item>
               <item id="3">003</item>
            </payload>
         ]]></pre:Request>
  </pre:getResponse>
</soap:Body>

However, this could easily fail if, for example, the CDATA section contains another </pre:Request> string within the outer "wrapper". The lesson here is that if you need to process the response, don't send it as CDATA.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM