to_json和to_xml在rails中提供不同的输出

时间:2012-11-22 00:11:28

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

在这里开始使用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和转换。如何将其格式化为与json相同?我也不想要任何标签上的属性。我知道你可以传入属性,例如:root =&gt; '回应',但在寻找相当长的一段时间后,我似乎无法在网上找到这些属性的列表。

非常感谢任何帮助,谢谢!

1 个答案:

答案 0 :(得分:1)

这是最好直接转到源代码的情况。 to_xml模块位于ActiveModel::Serializer模块中,此处为inline docs,其中未提及有关type="array"属性标记的任何内容。稍微挖一点,你会看到它们出现在名为add_associations的方法的第130行的同一文件中。

<强>导轨/ activemodel的/ LIB / active_model /串行化器/ 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 }