【问题标题】:to_json and to_xml giving different outputs in railsto_json 和 to_xml 在 rails 中给出不同的输出
【发布时间】:2012-11-10 08:14:42
【问题描述】:

在这里开始 Rails 程序员。我正在尝试将哈希转换为 xml 和 json,但输出不同。

这是哈希:

{:exchangeRates=>[{:baseCurrency=>"USD", :quoteCurrency=>"EUR", :amount=>1, :nprices=>1, :conversions=>[{:date=>Tue, 20 Nov 2012 21:00:00 +0000, :ask=>"0.7813", :bid=>"0.7813"}]}, {:baseCurrency=>"CAD", :quoteCurrency=>"EUR", :amount=>1, :nprices=>1, :conversions=>[{:date=>Tue, 20 Nov 2012 21:00:00 +0000, :ask=>"0.7839", :bid=>"0.7837"}]}]}

这是对应的渲染代码

format.json { render :json => { :response => rates.to_hash() } }

这是 JSON(这是我想要的)

{"response": {"exchangeRates": [
    {
        "baseCurrency": "USD",
        "quoteCurrency": "EUR",
        "amount": 1,
        "nprices": 1,
        "conversions": [{
            "date": "2012-11-20T21:00:00+00:00",
            "ask": "0.7813",
            "bid": "0.7813"
        }]
    },
    {
        "baseCurrency": "CAD",
        "quoteCurrency": "EUR",
        "amount": 1,
        "nprices": 1,
        "conversions": [{
            "date": "2012-11-20T21:00:00+00:00",
            "ask": "0.7839",
            "bid": "0.7837"
        }]
    }
]}}

这是我的 xml 渲染代码:

format.xml { render :xml => rates.to_hash(), :root => 'response' }

这是 xml 输出(我在数组中放置了额外的标签):

<response>
    <exchangeRates type="array">
        <exchangeRate>
            <baseCurrency>USD</baseCurrency>
            <quoteCurrency>EUR</quoteCurrency>
            <amount type="integer">1</amount>
            <nprices type="integer">1</nprices>
            <conversions type="array">
                <conversion>
                    <date type="datetime">2012-11-20T21:00:00+00:00</date>
                    <ask>0.7813</ask>
                    <bid>0.7813</bid>
                </conversion>
            </conversions>
        </exchangeRate>
        <exchangeRate>
            <baseCurrency>CAD</baseCurrency>
            <quoteCurrency>EUR</quoteCurrency>
            <amount type="integer">1</amount>
            <nprices type="integer">1</nprices>
            <conversions type="array">
                <conversion>
                    <date type="datetime">2012-11-20T21:00:00+00:00</date>
                    <ask>0.7839</ask>
                    <bid>0.7837</bid>
                </conversion>
            </conversions>
        </exchangeRate>
    </exchangeRates>
</response>

如您所见,它添加了额外的“数组”属性标签,即 exchangeRates 和 Conversions。我如何让它的格式与 json 相同?我也不想要任何标签上的属性。我知道你可以传入属性,例如 :root => 'response',但是找了很久,我似乎在网上找不到这些属性的列表。

任何帮助将不胜感激,谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby xml json activesupport


    【解决方案1】:

    在这种情况下,最好直接访问源代码。 to_xml 方法在ActiveModel::Serializer 模块中,这里是inline docs,没有提到任何关于type="array" 属性标签的内容。再深入一点,你会发现它们出现在同一个文件中的第 130 行,该方法名为 add_associations

    rails/activemodel/lib/active_model/serializers/xml.rb:130

    type = options[:skip_types] ? { } : {:type => "array"}
    

    这告诉我们有一个名为skip_types 的选项,似乎无处记录。尝试将其传递给to_xml,您将获得所需的行为:

    a = [1, 2, 3]
    a.to_xml
    #=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<fixnums type=\"array\">\n  <fixnum type=\"integer\">1</fixnum>\n  <fixnum type=\"integer\">2</fixnum>\n  <fixnum type=\"integer\">3</fixnum>\n</fixnums>\n"
    a.to_xml(:skip_types => true)
    #=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<fixnums>\n  <fixnum>1</fixnum>\n  <fixnum>2</fixnum>\n  <fixnum>3</fixnum>\n</fixnums>\n"
    

    您会注意到所有添加的type 属性都消失了。

    所以只需将相同的选项传递给render,您就会得到想要的结果:

    format.xml { render :xml => rates.to_hash(), :root => 'response', :skip_types => true }
    

    【讨论】:

    • 感谢您的回复。问题是,我想完全摆脱该数组标签,即,对于您的示例,我想要的 xml 将是:&lt;?xml version=1.0?&gt;&lt;fixnum&gt;1&lt;/fixnum&gt;&lt;fixnum&gt;2&lt;/fixnum&gt;&lt;fixnum&gt;3&lt;/fixnum&gt;。查看代码后,我认为这似乎是不可能的。也许我可以回到设计者那里,让他们更改输出以包含该包装器标记,因为这似乎是生成 xml 的正确方法。你怎么看?
    • 我明白了。但这不是你问的。您说您希望 xml 类似于 JSON,并且在 JSON 中有名为 "exchangeRates" 的键,后跟数组。如果您完全取出标签,那么(我看到它的方式)您正在创建与 JSON 不同的 xml。
    猜你喜欢
    • 1970-01-01
    • 2012-11-30
    • 2017-02-20
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多