通过XSLT将XML元素包含在CDATA部分中

4

我将尝试添加一个<![CDATA[]]>来包裹一组元素。

输入:

<?xml version="1.0" encoding="UTF-8"?>
<params>
  <param dataType="java.lang.String">respID</param>
  <param dataType="java.lang.Date">2015-11-04</param>
  <param dataType="java.lang.String">

     <XX_IL_OLM_COMP_ELEMENT_OBJ><P_OLM_COMP_ELEMENT>
<XX_IL_OLM_COMP_ELEMENT_OBJ>
    <P_ACTION>CREATE</P_ACTION>
    <p_activity_version_id>12</p_activity_version_id>
</XX_IL_OLM_COMP_ELEMENT_OBJ>
</P_OLM_COMP_ELEMENT>
</XX_IL_OLM_COMP_ELEMENT_OBJ>

  </param>
</params>

期望输出:

<?xml version="1.0" encoding="UTF-8"?>
<params>
  <param dataType="java.lang.String">respID</param>
  <param dataType="java.lang.Date">2015-11-04</param>
  <param dataType="java.lang.String">
<![CDATA[
     <XX_IL_OLM_COMP_ELEMENT_OBJ><P_OLM_COMP_ELEMENT>
<XX_IL_OLM_COMP_ELEMENT_OBJ>
    <P_ACTION>CREATE</P_ACTION>
    <p_activity_version_id>12</p_activity_version_id>
</XX_IL_OLM_COMP_ELEMENT_OBJ>
</P_OLM_COMP_ELEMENT>
</XX_IL_OLM_COMP_ELEMENT_OBJ>
]]>
  </param>
</params>

基本上,当我有param元素的子元素时,我需要将子元素包装在CDATA中。

1个回答

5

考虑以下输入XML:

<?xml version="1.0" encoding="UTF-8"?>
<params>
  <param dataType="java.lang.String">respID</param>
  <param dataType="java.lang.Date">2015-11-04</param>
  <param dataType="java.lang.String">

    <XX_IL_OLM_COMP_ELEMENT_OBJ><P_OLM_COMP_ELEMENT>
      <XX_IL_OLM_COMP_ELEMENT_OBJ>
        <P_ACTION>CREATE</P_ACTION>
        <p_activity_version_id>12</p_activity_version_id>
      </XX_IL_OLM_COMP_ELEMENT_OBJ>
    </P_OLM_COMP_ELEMENT>
    </XX_IL_OLM_COMP_ELEMENT_OBJ>

  </param>
</params>

这个XSLT将会用 CDATA 包装 param 子元素:
<?xml version="1.0" encoding="UTF-8"?>
<!-- This XSLT will wrap `param` element contents in CDATA:-->
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

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

      <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:transform>

并生成以下输出的XML:
<?xml version="1.0" encoding="UTF-8"?>
<params>
  <param dataType="java.lang.String">respID</param>
  <param dataType="java.lang.Date">2015-11-04</param>
  <param dataType="java.lang.String"><![CDATA[<XX_IL_OLM_COMP_ELEMENT_OBJ>
         <P_OLM_COMP_ELEMENT>
            <XX_IL_OLM_COMP_ELEMENT_OBJ>
               <P_ACTION>CREATE</P_ACTION>
               <p_activity_version_id>12</p_activity_version_id>
            </XX_IL_OLM_COMP_ELEMENT_OBJ>
         </P_OLM_COMP_ELEMENT>
      </XX_IL_OLM_COMP_ELEMENT_OBJ>]]></param>
</params>

非常好用!谢谢kjhuges。 - Sammy
你能否在以下网站分享你的知识: http://stackoverflow.com/questions/33810019/covert-an-xml-which-contains-lt-gt-in-it-using-xslt - Sammy
我很高兴这有所帮助。不用谢。关于你的另一个问题,Daniel Haley的回答没有帮到你吗?他和我都需要听到你的具体问题是什么。我建议你在他的回答下留言。谢谢。 - kjhughes
1
请注意,此解决方案仅在以下两种情况下有效:(a) 处理器支持disable-output-escaping,(b) 转换的输出直接输入到序列化程序中。 - Michael Kay
@MichaelKay:这里有没有更强大的替代方案可以用来解决这个问题? - kjhughes
1
@kjhughes:在3.0版本中,您可以使用<xsl:output cdata-section-elements="param"/>,然后使用<param>{serialize(*)}</param>,但是(a)这将使所有的param元素成为CDATA节,(b)它仍然只能在转换器与序列化程序耦合时才能工作——这是不可避免的,因为CDATA节不存在于XDM数据模型中。但真正的要求可能不是将内容包装在CDATA中,而是输出包含XML词汇字符串而不是元素标记,从这个意义上说,这个解决方案更加健壮。 - Michael Kay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接