`

rexml 中增加CDATA

    博客分类:
  • ruby
 
阅读更多
最近想用ruby写个能生成ibatis sqlmap的xml文件,以前一直没注意,找了下才发现自带的包中就有,那就是rexml,在生成普通的文本内容时没什么问题,今天突然准备把有些sql语句放在
<![CDATA[ ]]>里面,结果就是不能成功。不管怎么放,“〈〉”这两个尖括号都会被转义,在网上找了下也没发现什么答案,小众语言就是这样,找资料难。
  好不容易找到了一个关于cdata.rb的内容,虽然没怎么说清楚,但至少提供了思路,于是自己就看了下ruby lib中的cdata.rb的源码,有一个write可以用,用法如下:

c = CData.new( " Some text " )
c.write( $stdout )     #->  <![CDATA[ Some text ]]>


这个方法应该可行,它也继承自Text,也就是用于Text的地方也可用于CData,但是这个方法却写着deprecated标记,注释上说去看 rexml/formatters,于是自己找到该目录,下面有三个文件:default.rb pretty.rb transtive.rb,那么自己用的又是那个formatter呢? 由于输出的代码是这句:

doc.write(xmlFile,4)

于是自己找到document的write方法:

def write( output=$stdout, indent=-1, transitive=false, ie_hack=false )
      if xml_decl.encoding != "UTF-8" && !output.kind_of?(Output)
        output = Output.new( output, xml_decl.encoding )
      end
      formatter = if indent > -1
          if transitive
            require "rexml/formatters/transitive"
            REXML::Formatters::Transitive.new( indent, ie_hack )
          else
            REXML::Formatters::Pretty.new( indent, ie_hack )
          end
        else
          REXML::Formatters::Default.new( ie_hack )
        end
      formatter.write( self, output )
    end

因为indent为4,所以应该采用的是Pretty这个formatter,毫不犹豫的打开pretty.rb这个文件,看了几分钟,除了一个名叫write_cdata的方法有点像以外,没发现什么特别的:
def write_cdata( node, output)
        output << ' ' * @level
        super
      end

但这个方法也没什么特别的,非常的普通,怎么看都不会输出"<![CDATA ]]>"这些东西,于是只能看看其父类有没有什么特别的了。因为pretty的父类是default,于是找到default的write_cdata方法:

      def write_cdata( node, output )
        output << CData::START
        output << node.to_s
        output << CData::STOP
      end

答案找到了,问题似乎解决了,于是自己写了个简单的语句测试了下:
t = REXML::Formatters::Default.new
 puts t.write_cdata("fff",$stdout);

但控制台提示write_cdata方法是pretected的,外部不能使用,那怎么办呢?最后看了半天才找到答案,自己忽略了document中write的最后一句话:
formatter.write( self, output )


这句话比较关键,于是找到Default的write方法:
def write( node, output )
        case node

        when Document
          if node.xml_decl.encoding != "UTF-8" && !output.kind_of?(Output)
            output = Output.new( output, node.xml_decl.encoding )
          end
          write_document( node, output )

        when Element
          write_element( node, output )

        when Declaration, ElementDecl, NotationDecl, ExternalEntity, Entity,
             Attribute, AttlistDecl
          node.write( output,-1 )

        when Instruction
          write_instruction( node, output )

        when DocType, XMLDecl
          node.write( output )

        when Comment
          write_comment( node, output )

        when CData
          write_cdata( node, output )

        when Text
          write_text( node, output )

        else
          raise Exception.new("XML FORMATTING ERROR")

        end
      end

终于找到答案了,内容的格式是由node的类型决定的,也就是说,只要创建一个CData对象,将此对象赋给Text即可,document知道怎么输出:
_cdata = CData.new "select * from \n(select rownum as r,s.* from 
	      (select #{_field_as_attr*','} from #{@@table}"
_select_all.text=_cdata

这样输出的xml就会包含在"<![CDATA[]]>"内。而且由上面default.write方法可以看出,如果要加入其它结点类型,比如Comment、DocType、XMLDecl等类型时,只需要创建相应的对象,然后添加进相应的对象即可,相应的格式自然就可以生成了。

这个问题几乎花了自己一上午的时间,虽然ruby以前也有学过,但一直没怎么用,几乎都忘光了,昨几天才书店偶然看见了ruby之父松本行弘(这个名字很不好记)的一本书叫 松本行弘的程序世界,发行这本书写得挺不错的,上面说到可以用ruby来写些工具类用用,于是再次拿起原来的那本ruby programming看了看,两三天的时间基本上就把生成ibatis的sqlmap文件,基本的dao、service、domain之类的东西就写成了,效率确实远高于用java来写,然后在网上把那本<松本行弘的程序世界>买了下来(网上买七五折不加邮费,确实比书店的便宜多了,鄙人在新华书店买了不少书,从来没打折)。ruby确实是一门很有意思的语言,在开发过程中总会有些地方让自己惊讶与欣喜,这是使用其它任何语言都未有过的,特别是java,用java开发程序这么久,基本上都是厌倦。

10.19:另外,如果想在各个element这间加上空白换行符,如:
    <select id="getUserTypeNextId" resultClass="long">
    </select>

    <insert id="addUserType" parameterClass="userType">
    </insert>

    <update id="updateUserType" prameterClass="string">
    </update>

    <delete id="deleteUserType" parameterClass="string">
    </delete>

这个问题本人看了文档,主要看了Element与 Document这两个类,均没有什么收获,于是再去看了下Formatters模块的Pretty,也没发现什么参数可用,看来只能改源代码了。直接修改Pretty的write_element方法:
      def write_element(node, output)
        .........
        end
        output << ">"
        output << "\n"
      end

也就是在该元素最后一行加上换行符就行了。
分享到:
评论
2 楼 sdxshx 2012-09-11  
楼主很认真
1 楼 yanzilee9292 2012-01-06  
好东西 ruby处理xml确实很简单嘛

相关推荐

    asp.net自带类读写xml中的CDATA

    在处理XML时,有时我们需要读取或写入CDATA节中的内容。ASP.NET 3.5及以上版本提供了内置的序列化类,使得操作XML中的CDATA变得简单,同时也支持JSON数据格式的读写。 本文将详细介绍如何利用ASP.NET的内置类来读写...

    包含CDATA的 字符串转换成xml

    本文档包含了一个完整的实例,可以实现含有CDATA 的字符串转换成xml

    android SaxParser 解析 CDATA

    本篇将详细介绍如何在Android中使用SAXParser来解析包含CDATA(Character Data)的XML数据。 首先,了解CDATA的概念。在XML中,CDATA段是用来标记一段文本,告诉解析器这段文本不应被解析为XML元素。它的语法是`&lt;!...

    JAVA对象转换成XML(CDATA)

    在Java编程中,将对象转换成XML是一种常见的数据序列化方式,这有助于数据交换和存储。当遇到包含特殊字符如 "和 "&" 的文本时,XML解析器可能会产生错误,因为这些字符在XML语法中有特定含义。为了解决这个问题,...

    XML:标签CDATA用法

    ### XML中的CDATA用法详解 #### 一、CDATA的基本概念 **CDATA**(Character Data)是一种特殊的文本区域,它被XML解析器视为纯文本数据,并不会对其进行解析或处理。这意味着在CDATA段落内的任何XML标签或者实体引用...

    区分CDATA和PCDATA

    在深入探讨CDATA与PCDATA的区别之前,我们先来理解它们在XML(可扩展标记语言)中的基本概念。XML是一种用于标记数据的语言,它允许自定义标签,因此在各种应用程序之间交换数据时非常灵活。然而,XML对特殊字符的...

    5、CDATA 和转义字符1

    另一方面,如果知道字符串中包含很多特殊字符,使用CDATA块可以避免频繁的转义操作,从而提高解析速度。 举一个实际应用的例子,假设我们在一个XML配置文件中定义SQL查询,其中包含比较运算符,如"和"&gt;",我们可以...

    CData.rar_cdata

    "CData.rar_cdata"这个压缩包显然是为了帮助学习者深入理解和掌握C语言而准备的。让我们来详细探讨一下这个资源包中可能包含的知识点。 首先,"C资料大全.doc"很可能是一份详尽的C语言教程或参考资料。这样的文档...

    如何处理xml中的CDATA脚本

    本文将详细探讨如何在C#环境中处理XML中的CDATA脚本。 首先,理解CDATA的语法是至关重要的。CDATA区段通常以`&lt;![CDATA[`开始,以`]]&gt;`结束,其中间的任何字符都不会被XML解析器解析为XML元素或实体。例如: ```xml...

    C#读取XML的CDATA节点内容实例详解

    在本篇文章中,我们将详细介绍如何使用C#语言读取XML文件中的CDATA节点内容。CDATA节点是一种特殊的XML节点,用于存储不需要被XML解析器解析的文本数据。在实际开发中,我们经常需要读取CDATA节点中的数据,以便进行...

    javascript语句中的CDATA标签的意义

    ### JavaScript语句中的CDATA标签的意义 #### 一、引言 在现代Web开发中,JavaScript是一种必不可少的编程语言,它不仅被广泛应用于浏览器端的脚本编写,还常常与HTML和CSS结合使用来构建动态网页。然而,在某些...

    页里面 CDATA的作用说明

    CDATA(Character Data)的主要作用是将特殊字符或实体引用包装到CDATA节中,以避免浏览器对这些字符的解析。通常情况下,CDATA节用于Script和Style元素中,以便正确地呈现JavaScript代码和CSS样式规则。 在HTML文...

    php生成xml时添加CDATA标签的方法

    CDATA部分会告诉XML解析器忽略内部文本中的特殊字符,如", "&gt;", "&"等,它们会被当作普通字符处理。 PHP提供了DOMDocument类用于操作XML文件,包括创建、编辑和输出。DOMDocument类中的createCDATASection方法可以...

    Mybatis 中的&amp;lt;![CDATA[ ]]&amp;gt;浅析

    [CDATA[ ]]&gt; 可以将特殊字符(如 `、`&gt;`、`&` 等)包含在 XML 文件中,使得这些特殊字符不被解析器转义。 2. 提高代码可读性:使用 &lt;![CDATA[ ]]&gt; 可以将复杂的 SQL 语句包含在 XML 文件中,使得代码更加简洁和易读...

    H3CData高校大数据解决方案

    - **功能介绍**:H3C高校大数据应用中的就业分析模块能够深度分析就业率、薪酬、就业行业等多个维度的数据,帮助高校了解学生就业情况。 - **作用**:该模块可为学生提供专业选择建议,为毕业生提供就业指导,并为...

    PHP cdata 处理(详细介绍)

    为了解决这个问题,可以编写一个CDATA解析器,即一个状态机,该状态机可以识别XML中的CDATA部分,并将其从XML文本中提取出来。上面提供的PHP代码片段,就是一个实现状态机逻辑的示例。代码通过分析XML字符串中的字符...

    网页中CDATA标记的说明

    CDATA是在XML文档里面使用的关键字,用来告诉浏览器,这部分内容不用解析,是给其他程序用的,比如JAVASCRIPT等等。 PCDATA是在 XML约束文档里使用的,如DTD类型的约束文档,在这里面表示元素的内容或属性的取值范围...

    php操作xml入门之cdata区段

    XML文档中使用CDATA区段的方式非常简单,它由“&lt;![CDATA[”开始,并以“]]&gt;”结束。CDATA区段内的内容将不会被XML解析器进行解析。 在本教程中,我们将看到一个具体的XML文档示例。这个文档定义了一个学生的个人...

Global site tag (gtag.js) - Google Analytics