首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Ruby ROXML -如何获取数组来呈现其xml?

Ruby ROXML -如何获取数组来呈现其xml?
EN

Stack Overflow用户
提问于 2010-05-16 22:29:29
回答 1查看 1.2K关注 0票数 0

我正在尝试创建一个继承Array的Messages对象。消息将收集一组消息对象。我正在尝试使用ROXML创建一个xml输出,如下所示:

代码语言:javascript
复制
<messages>
    <message>
        <type></type>
        <code></code>
        <body></body>
    </message>
    ...
</messages>

但是,我不知道如何让Messages对象中的message对象显示在xml中。下面是我一直在使用的代码:

代码语言:javascript
复制
require 'roxml'

class Message
  include ROXML

  xml_accessor :type
  xml_accessor :code
  xml_accessor :body
end

class Messages < Array
  include ROXML

  # I think this is the problem - but how do I tell ROXML that
  # the messages are in this instance of array?
  xml_accessor :messages, :as => [Message]

  def add(message)
    self << message
  end

end


message = Message.new
message.type = "error"
message.code = "1234"
message.body = "This is a test message."

messages = Messages.new
messages.add message

puts messages.length
puts messages.to_xml

这将输出以下内容:

代码语言:javascript
复制
1
<messages/>

因此,我添加到消息中的消息对象不会显示。有谁有什么想法吗?还是说我走错了路?

谢谢你的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-05-17 08:43:02

我不认为你想要的是可能的。您试图以某种方式访问Array类的内部状态,这不仅是不可能的,因为在大多数实现中,这些内部都隐藏在C/C++/Java/.NET/Objective-C/ABAP运行时中,而且这是一个非常糟糕的想法和糟糕的面向对象设计。

问题是,Messages实际上不是一个Array,因此它不应该继承自Array。告诉我:您真的100%确定您的Messages类能够忠实地履行Array上所有81个方法的约定吗?当应用于Messages时,assocrassocrindextranspose到底意味着什么

在这里,你最好使用委托而不是继承。这为您提供了一个很好的命名实体,您可以将其传递给xml_accessor

代码语言:javascript
复制
require 'forwardable'
require 'roxml'

class Messages
  extend Forwardable
  include ROXML

  class << self; alias_method :[], :new end

  xml_reader :messages, :as => [Message]

  def initialize(*messages) @messages = messages end

  def_delegators :messages, :length, :<<
end

注意:我还在这里更改了几个其他的东西。例如,我个人认为一个对象在构造之后应该是有效和可用的。在您的代码版本中,Message在构造后基本上是无效的,只有在调用type=code=body= setter之后才会生效:

代码语言:javascript
复制
class Message
  include ROXML

  class << self; alias_method :[], :new end

  xml_reader :type, :body
  xml_reader :code, :as => Integer

  def initialize(type=nil, code=nil, body=nil)
    @type, @code, @body = case opts = type
    when Hash
      opts[:type], opts[:code], opts[:body]
    else
      type, code, body
    end
  end
end

下面是一个略微扩展的用法示例:

代码语言:javascript
复制
msgs = Messages[Message['error', 1234, 'This is a test message.'], Message[]]

msgs << Message[
  type: 'warning', 
  code: 4815162342, 
  body: 'This is another test message.'
]

puts msgs.to_xml
# => <messages>
# =>   <message>
# =>     <type>error</type>
# =>     <body>This is a test message.</body>
# =>     <code>1234</code>
# =>   </message>
# =>   <message/>
# =>   <message>
# =>     <type>warning</type>
# =>     <body>This is another test message.</body>
# =>     <code>4815162342</code>
# =>   </message>
# => </messages>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2844106

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档