简体   繁体   English

使用xslt将XML元素从其位置移动到另一个父元素下

[英]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. 我正在尝试移动xml元素的位置,并将其环绕在将来的父元素下的所有其他元素。

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. 在这里,我在xml中添加了一个cdata标记,它包装在其他元素周围也很好。 I'd like to do something similar only this time, the tag is already in the xml: 我只想这次做类似的事情,标签已经在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". 正如我在对问题的评论中提到的那样,输入XML代码段中没有pre:Request元素,因此无法“移动”它。 The entire CDATA section is just a meaningless string, containing no markup. 整个CDATA部分只是一个毫无意义的字符串,不包含任何标记。

You could try removing the unwanted portion by string manipulation: 您可以尝试通过字符串操作删除不需要的部分:

XSLT 1.0 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 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". 但是,例如,如果CDATA节在外部“包装器”中包含另一个</pre:Request>字符串,则很容易失败。 The lesson here is that if you need to process the response, don't send it as CDATA. 这里的教训是,如果您需要处理响应,请不要将其作为CDATA发送。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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