- 浏览: 161956 次
- 性别:
- 来自: 华东
文章分类
最新评论
-
chen_miao:
我是初学者,请问,我在flex设计好了带有按钮和下拉框的界面, ...
ruby+flex实现天气预报 -
barrytyh:
很多技术人员都有想法,但忘了一个根本性的问题,谁在给你MONE ...
互联网创业与软件开发 -
fireflyman:
囧......
关于并发和并行 -
fireflyman:
你老再次出现了
谈谈互联网新产品如何起步 -
qhh394141930:
写得很详细,受教了。谢谢!
从瀑布模型、极限编程到敏捷开发
在开发RESTful应用或者实现多个应用系统交互时,经常会用到XML作为数据交换格式,系统会经常处理XML数据,采用ROXML将会是一个不错的方案,ROXML是一个实现ruby对象和XML进行映射的库,通过annotations声明,它也可以将xml数据节点映射为ruby类的属性,以及把XML的节点关系映射为ruby类之间的关系,个人觉得,它的作用类似于ActiveRecord将ruby对象映射为数据库表。
它可以:
1 读取xml生成ruby对象
2 将ruby对象输出为xml格式
3 很灵巧的映射配置,包括一对一以及一对多
4 支持基于UTF-8的多语言文档
在此处可以下载该库 http://rubyforge.org/projects/roxml ,这里有一个图书馆和图书的例子,以此说明ROXML处理一对多的情况。
生成相应的ruby类
class Book include ROXML xml_attribute :isbn, "ISBN" xml_text :title xml_text :description, nil, ROXML::TAG_CDATA xml_text :author end class Library include ROXML xml_text :name, "NAME", ROXML::TAG_CDATA xml_object :books, Book, ROXML::TAG_ARRAY, "books" end
分别创建Library对象和Book对象,并将book放入library中,最后保存输出。
book = Book.new() book.isbn = "0201710897" book.title = "The PickAxe" book.description = "Best Ruby book out there!" book.author = "David Thomas, Andrew Hunt, Dave Thomas" lib = Library.new() lib.name = "Favorite Books" lib.books << book
File.open("library.xml", "w") do |f| lib.to_xml.write(f, 0) end
可以看到生成的xml为:
<library> <NAME><![CDATA[Favorite Books]]></NAME> <books> <book ISBN='0201710897'> <title>The PickAxe</title> <description><![CDATA[Best Ruby book out there!]]></description> <author>David Thomas, Andrew Hunt, Dave Thomas</author> </book> </books> </library>
同理,也可以根据xml数据创建ruby对象,这里再举个一对一的例子,假设有以下的xml文档,描述了图书与作者的关系。
<book isbn="0974514055"> <title>Programming Ruby - 2nd Edition</title> <description>Second edition of the great book</description> <publisher> <name>Pragmatic Bookshelf</name> </publisher> </book>
那么生成ruby类与之对应:
class BookWithPublisher include ROXML xml_name :book xml_object :publisher, Publisher end
最后可以读取先前的xml文档并生成相应的ruby对象了,此时可以操作book对象来达到对xml文档进行处理。
book = Book.parse(File.read("book.xml"))
评论
11 楼
jimmy
2009-03-11
devercn 写道
liuqiang,你好,看了你关于ROXML的介绍之后,下载试用,发现ROXML对中文的支持不好,to_xml出来的结果都是乱码,不知你遇到没有,请问如何解决?
require "roxml"
module ROXML
class XMLAttributeRef < XMLRef # :nodoc:
private
# Updates the attribute in the given XML block to
# the value provided.
def write_xml(xml, value)
xml.attributes[name] = value.to_s
end
end
class XMLTextRef < XMLRef # :nodoc:
delegate :cdata?, :content?, :name?, :to =>pts
private
def add(dest, value)
if cdata?
dest.child_add(XML::Node.new_cdata(value.to_s))
else
dest.content = value.to_s
end
end
end
end
另外
1、在你代码中加 $KCODE = 'utf8'
2、打开保存xml时加encoding
doc.save("library.xml", :encoding => LibXML::XML::Encoding::UTF_8)
doc = LibXML::XML::Document.file("library.xml", :encoding => LibXML::XML::Encoding::UTF_8)
lib = Library.from_xml(doc)
10 楼
devercn
2009-03-11
liuqiang,你好,看了你关于ROXML的介绍之后,下载试用,发现ROXML对中文的支持不好,to_xml出来的结果都是乱码,不知你遇到没有,请问如何解决?
9 楼
CharlesCui
2008-11-16
liuqiang11 写道
我对你的需求的理解是,有2个哈希,哈希可能还存在嵌套,只要这2个哈希的key,包括嵌套的hash的key相同,顺序可以不同,那么这2个hash则认为是相等的。
强强能够理解我的意思,但是你为什么不考虑value啊?差一半就被你搞定了。
我再给强强补充下:
如果有如下两个hash分别为h1和h2,那该如何比较呢?
h1={"servlet"=> {"load_on_startup"=>"1", "servlet_name"=>"default", "init_param"=> [{"param_name"=>"debug", "param_value"=>"0"}, {"param_name"=>"listings", "param_value"=>"false"}], "servlet_class"=>"org.apache.catalina.servlets.DefaultServlet"}} "****************************************************************************************************" h2={"servlet"=> {"load_on_startup"=>"1", "servlet_name"=>"default", "init_param"=> [{"param_name"=>"listings", "param_value"=>"false"}, {"param_name"=>"debug", "param_value"=>"0"}], "servlet_class"=>"org.apache.catalina.servlets.DefaultServlet"}}
现实中的问题是,从一个xml解析而来的hash你不会知道它每个key的value类型,可能是hash,也可能是数组,或者是别的。
请给出一个通用的方法。
强强,再加油一把,期待你的完美表现!
PS:请以我之前给出的那两个xml片段来比较吧,这两个hash就是从那两个hash解析来的。
8 楼
liuqiang
2008-11-16
<p>我对你的需求的理解是,有2个哈希,哈希可能还存在嵌套,只要这2个哈希的key,包括嵌套的hash的key相同,顺序可以不同,那么这2个hash则认为是相等的。</p>
<p> </p>
<p>貌似ruby没有内置的api可以用,我觉得还是设计一个小算法自己做,我的思路是遍历hash中的所有key,包括嵌套hash的key,将第一层hash的key以及它的子哈希的key组成一个字符串,并以逗号隔开,再这些字符串存进数组,最后通过比较数组来确定这2个hash是否相等。</p>
<p> </p>
<p>测试代码如下:</p>
<p> </p>
<pre name='code' class='ruby'>class A
@@a = []
@@str = ""
def A.xxx(h)
h.each do |key, val|
if val.class.to_s == "Hash"
@@str = @@str + key.to_s + ","
xxx(val)
else
@@str = @@str + key.to_s
@@a << @@str
@@str = ""
end
end
end
def A.getA()
return @@a
end
def A.setA()
@@a = []
end
end
h1 = {'a1'=>1,'a2'=>{'b2'=>1},'a3'=>{'b3'=>{'c3'=>1}}}
h2 = {'a3'=>{'b3'=>{'c3'=>1}},'a1'=>1,'a2'=>{'b2'=>2}}
A.setA
A.xxx(h1)
a = A.getA
puts A.getA
A.setA
A.xxx(h2)
b = A.getA
puts b
puts a.eql?(b)</pre>
<p> </p>
<p> </p>
<p>写的很差,仅供参考</p>
<p> </p>
<p>貌似ruby没有内置的api可以用,我觉得还是设计一个小算法自己做,我的思路是遍历hash中的所有key,包括嵌套hash的key,将第一层hash的key以及它的子哈希的key组成一个字符串,并以逗号隔开,再这些字符串存进数组,最后通过比较数组来确定这2个hash是否相等。</p>
<p> </p>
<p>测试代码如下:</p>
<p> </p>
<pre name='code' class='ruby'>class A
@@a = []
@@str = ""
def A.xxx(h)
h.each do |key, val|
if val.class.to_s == "Hash"
@@str = @@str + key.to_s + ","
xxx(val)
else
@@str = @@str + key.to_s
@@a << @@str
@@str = ""
end
end
end
def A.getA()
return @@a
end
def A.setA()
@@a = []
end
end
h1 = {'a1'=>1,'a2'=>{'b2'=>1},'a3'=>{'b3'=>{'c3'=>1}}}
h2 = {'a3'=>{'b3'=>{'c3'=>1}},'a1'=>1,'a2'=>{'b2'=>2}}
A.setA
A.xxx(h1)
a = A.getA
puts A.getA
A.setA
A.xxx(h2)
b = A.getA
puts b
puts a.eql?(b)</pre>
<p> </p>
<p> </p>
<p>写的很差,仅供参考</p>
7 楼
CharlesCui
2008-11-16
还有,
liusong1111,你上面介绍的操作xml的库和activeSupport这个库都有一个类似的方法就是Hash.frmo_xml.
我一直想问的问题是两个只有element顺序不同的xml片段如何比较?
你的意思是不是变成hash后再用eql?或者==来比较?可问题是,hash的子元素的类型不一定啊,说不定是数组或者别的呢,如果是数组,那就肯定不相同了,数组是有顺序的。
你试试下面的代码就理解我的意思了:
liusong1111,你上面介绍的操作xml的库和activeSupport这个库都有一个类似的方法就是Hash.frmo_xml.
我一直想问的问题是两个只有element顺序不同的xml片段如何比较?
你的意思是不是变成hash后再用eql?或者==来比较?可问题是,hash的子元素的类型不一定啊,说不定是数组或者别的呢,如果是数组,那就肯定不相同了,数组是有顺序的。
你试试下面的代码就理解我的意思了:
require 'rubygems' require 'pp' require 'active_support' xml1=<<-XML <servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> XML xml2=<<-XML <servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-value>false</param-value> <param-name>listings</param-name> </init-param> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> XML h1=Hash.from_xml xml1 h2=Hash.from_xml xml2 pp h1 p "*"*100 pp h2 p "*"*100 p h1==h2
6 楼
CharlesCui
2008-11-16
hozaka 写道
CharlesCui 写道
xml变成了hash后如何比较?
通过内建的==是无法比较两个有相同键值对的hash的,因为只要键值对顺序不同,==方法就认为不同。
通过内建的==是无法比较两个有相同键值对的hash的,因为只要键值对顺序不同,==方法就认为不同。
- Hash 是无序的,不存在“键值对顺序”的说法,http://ruby-doc.org/core/classes/Hash.html#M002875
- 在 Hash#== 中,体会一下递归的作用
- Module#== 方法的实现原理,尤其是对于复杂的对象,在 override 的时候需要做什么
我没说hash是有序的,我是说ruby内建的==方法可能是有序的。
5 楼
liusong1111
2008-11-15
hozaka 写道
跑下题,ruby1.9的key按插入顺序排列了:
http://intertwingly.net/slides/2008/oscon/ruby19/22
这个特性是fiber之后最吸引我的了,会大大加强语言的表达能力。
4 楼
hozaka
2008-11-15
CharlesCui 写道
xml变成了hash后如何比较?
通过内建的==是无法比较两个有相同键值对的hash的,因为只要键值对顺序不同,==方法就认为不同。
通过内建的==是无法比较两个有相同键值对的hash的,因为只要键值对顺序不同,==方法就认为不同。
- Hash 是无序的,不存在“键值对顺序”的说法,http://ruby-doc.org/core/classes/Hash.html#M002875
- 在 Hash#== 中,体会一下递归的作用
- Module#== 方法的实现原理,尤其是对于复杂的对象,在 override 的时候需要做什么
3 楼
CharlesCui
2008-11-15
<div class='quote_title'>liuqiang 写道</div><div class='quote_div'><div class='quote_title'>CharlesCui 写道</div>
<div class='quote_div'>xml变成了hash后如何比较?<br/><br/>通过内建的==是无法比较两个有相同键值对的hash的,因为只要键值对顺序不同,==方法就认为不同。</div>
<p> </p>
<p>if (h1.keys).eql?(h2.keys)</p></div><br/>没用,你怎么知道一个hash有多少个key呢?hash里面还会有hash的。
<div class='quote_div'>xml变成了hash后如何比较?<br/><br/>通过内建的==是无法比较两个有相同键值对的hash的,因为只要键值对顺序不同,==方法就认为不同。</div>
<p> </p>
<p>if (h1.keys).eql?(h2.keys)</p></div><br/>没用,你怎么知道一个hash有多少个key呢?hash里面还会有hash的。
2 楼
liuqiang
2008-11-15
<div class='quote_title'>CharlesCui 写道</div>
<div class='quote_div'>xml变成了hash后如何比较?<br/><br/>通过内建的==是无法比较两个有相同键值对的hash的,因为只要键值对顺序不同,==方法就认为不同。</div>
<p> </p>
<p>if (h1.keys).eql?(h2.keys)</p>
<div class='quote_div'>xml变成了hash后如何比较?<br/><br/>通过内建的==是无法比较两个有相同键值对的hash的,因为只要键值对顺序不同,==方法就认为不同。</div>
<p> </p>
<p>if (h1.keys).eql?(h2.keys)</p>
1 楼
CharlesCui
2008-11-15
xml变成了hash后如何比较?
通过内建的==是无法比较两个有相同键值对的hash的,因为只要键值对顺序不同,==方法就认为不同。
通过内建的==是无法比较两个有相同键值对的hash的,因为只要键值对顺序不同,==方法就认为不同。
发表评论
-
创建你自己的rails generator
2010-01-27 15:01 1218在多个rails项目中,有时需要共享一些公用的componen ... -
rspec实践一(从零开始)
2009-12-25 12:52 1379关于利用rspec的文章感 ... -
javascript-image-cropper-ui with rails
2009-07-31 23:18 1497在rails上传头像的过程中,一般后端会采用rma ... -
简简单单在rails中做定时任务
2009-07-27 19:58 3384在平时的开发过程中,经常会遇到一些定时任务的需求 ... -
用restful_authentication和role_requirement搭建验证授权系统
2008-09-30 21:20 1552转自 http://fanix.iteye.com/blog/ ... -
Rails中html_escape和sanitize
2008-09-26 13:33 2554转自:http://blackanger.blog.51cto ... -
Rails简洁的模板系统Malline
2008-09-14 15:25 1402前段时间听说ra ... -
在rails中优雅的进行模型校验
2008-09-07 20:53 2186在用rails进行开发时,最常见的操作的是前台提交 ... -
win+apache+mongrel下部署ROR
2008-09-01 20:16 1138gem install mongrel #选择最 ... -
Ruby中使用Memecached
2008-09-01 20:03 1293sudo apt-get install memcached ... -
在rails中使用memcached
2008-09-01 20:00 1123libeven memcached的使用需要li ... -
在Ruby中设计Callback机制
2008-08-31 21:11 1935阅读Paperclip源码,发现里面有一个不错的callbac ... -
我怎么就觉得rails适合做大型应用
2008-08-25 13:24 3512之前读了不少 ... -
ImageMagick/Rmagick 安装的那些事儿
2008-08-05 12:54 1169windows平台×××××××××××××××××××××× ... -
让google来为rails画图表
2008-07-26 17:05 1365去年年底的时候,所做的一个rails项目涉及到图表 ... -
10分钟给一个rails遗留系统添加标签功能
2008-07-19 10:18 987早些时候做过了一个rails系统,当时没有涉及到标签的功 ... -
让rails处理图片再简单一点
2008-07-14 18:25 3059先来看看rails处理图片的过程吧,用户上传图片, ... -
分享一款word风格的rails在线编辑器
2008-07-09 16:51 1502在线编辑器是web应用中最常见的东西了,关于它的作用 ... -
让rails处理图片再简单一点
2008-07-07 12:50 1109先来看看rails处理图片的过程吧,用户上传图片, ... -
利用rails轻松建立个性化主页门户
2008-07-04 12:10 1115简单来说,个性化主页就是结合了各种小模块和网络信息 ...
相关推荐
通过定义简单的类和模块,HappyMapper能够自动将XML元素映射到Ruby类的属性上,这样我们就可以像操作普通的Ruby对象一样操作解析后的XML数据。 在实际应用中,首先我们需要包含HappyMapper库,并创建一个继承自...
自动注入基本 CURD 操作,几乎无性能损失,你可以像操作对象一样直接进行数据库操作,通过 BaseMapper 和 BaseService,使得 CRUD 操作变得极其简单。 3. **强大的 CRUD 功能**: 内置通用 Mapper 和通用 Service...
12. **物理分页插件**:MP提供了物理分页功能,开发者无需关注底层实现,写分页查询就像普通List查询一样简单。 13. **性能分析插件**:能够输出SQL语句及其执行时间,便于在开发和测试阶段发现慢查询。 14. **...
ActiveRecord模式将数据存储的概念与业务对象结合,使得开发者可以像操作普通对象一样操作数据库记录,降低了数据库操作的复杂性。 ** Castle简单实例** 在这个"Castle简单实例"中,我们可以预期看到如何使用...
ActiveRecord将数据库表映射为对象,使得数据库操作就像操作对象属性一样简单。 六、RESTful API支持 Yii框架对构建RESTful Web服务提供了很好的支持,可以方便地创建和消费JSON或XML格式的API。这在现代Web应用和...
Record模式允许开发者直接对数据库表进行操作,就像操作Java对象一样,极大地提高了开发效率。同时,JFinal还提供了拦截器、插件等机制,增强了灵活性和可扩展性。 在将Spring Boot和JFinal集成时,首先需要在...
DB模块是xUtils内置的数据库操作组件,基于ActiveRecord模式,让数据库操作如同操作Java对象一样简单。只需定义数据模型类,xUtils就能自动创建表、插入、查询、更新和删除数据。 6. **IO模块** IO模块提供了便捷...
它实现了对象关系映射(ORM),将数据库表映射为Ruby类,使得开发者可以像操作普通对象一样操作数据库记录。 2. **ActionController**:处理HTTP请求,并调用模型来执行业务逻辑,然后将结果传递给视图进行渲染。...
7. **hutool-db**:基于ActiveRecord思想的数据库操作封装,简化JDBC操作。 8. **hutool-dfa**:基于确定有限状态自动机(DFA)的多关键字查找。 9. **hutool-extra**:第三方库的封装,如模板引擎、邮件、Servlet、...
JFinal 的设计目标是使得 Java 开发能够像 Ruby、Python 和 PHP 等动态语言一样高效。 JFinal 的主要特点包括: - **MVC 架构**:精巧的设计,易于使用。 - **COC 原则**:即“Convention Over Configuration”...
例如,你可以对字符串进行操作,就像对待一个对象一样,调用它的方法如`length`来获取字符串的长度。 Ruby的语法简洁明了,易于学习。它采用了块(Blocks)和闭包(Closures)的概念,这使得处理迭代和异步操作变得...
etmvc的命名灵感来源于1982年的电影《E.T.》,寓意着它像外星人一样自由、不受传统框架的约束,旨在让开发者能够在轻松愉快的状态下进行Web应用开发。 #### 二、etmvc的特点 - **简易性**:代码简洁易懂,开发过程...
ActiveRecord提供了丰富的查询接口,包括链式查询,使得数据库操作如同操作Ruby对象一样直观。 Ruby的元编程能力是其独特之处,它允许在运行时修改和创建类及方法,这在其他语言中并不常见。这种能力使得Ruby代码...
Rails的ActiveRecord简化了与数据库的交互,通过ORM(对象关系映射)将数据库表与Ruby类关联起来,使得数据操作如同操作对象一样简单。 另外,为了保证用户的安全,Rails内置了CSRF(跨站请求伪造)和XSS(跨站脚本...
这个项目可能包含一系列的练习、挑战或者小任务,鼓励用户每天投入一定时间进行学习和编码,就像慢跑一样,每天坚持一小段距离,日积月累,可以显著提高健康状况。在Ruby的世界里,这种持续的练习同样能够提升编程...
- **第一类对象**:JavaScript中的函数是第一类对象,可以像其他对象一样赋值给变量、存储在数据结构中或作为参数传递给其他函数。 - **闭包**:函数可以访问其外部作用域中的变量,即使外部作用域已经关闭也是如此...