2

I have a problem that sounds basic, but I haven't found a solution anywhere. I'm using the Ruby version of XmlSimple, specifically the xml_out function.

The Problem

I'm having trouble outputting an element which would have one attribute node and a text node. Here's what I want:

<lane id='1'>unchannelized</lane>

Here's what I currently get:

<lane id='1'>
  <content>unchannelized</content>
</lane>

I've tried to use the "ContentKey" => 'content' option to xml_out (in addition to the "AttrPrefix" => true), but that yielded the same result. I've tried to change the ContentKey as well, same difference.

Relevant Code

The attribute & text node getting added to an array:

laneConfigArr << {"@id" => laneNo,  "content" => netsimLaneChannelizationCode(matchArr[matchIndex])}

The actual hash being generated:

unhappyHash << {
   #more stuff here,
   "LaneConfig" => {"lane" => laneConfigArr},
   #more stuff here
}

The xml_out call [EDITED]:

result["NetsimLinks"] = {"NetsimLink" => unhappyHash}
doc = XmlSimple.xml_out(result, {"AttrPrefix" => true, "RootName" => "CORSIMNetwork", "ContentKey" => "content"})

Environment Details

  • OS: Windows 7
  • Ruby: 1.9.3-p125
  • XmlSimple: 1.0.13

Looked everywhere, no-one seems to have had this problem. Perhaps I'm missing something, or maybe this cannot/shouldn't be done?

I'd highly appreciate any help with this.

Greg Kramida
  • 4,064
  • 5
  • 30
  • 46
  • Why are you passing the output to REXML? – Mark Thomas Apr 03 '12 at 16:29
  • Good point, because in the XmlSimple reference they add a space to the REXML document before writing it to file. I don't really care about that, so I can bypass it. It's irrelevant to the problem. If I don't do it, I get the same result. – Greg Kramida Apr 03 '12 at 16:35

2 Answers2

3

The nice thing about XmlSimple is that it is round-trippable: that is, you can put your desired output through xml_in and it will give you what you need to produce it with xml_out.

So let's take a look. Say we have the following simplified XML:

require 'xmlsimple'

xml = %Q(
  <CORSIMNetwork>
    <lane id='1'>unchannelized</lane>
  </CORSIMNetwork>
)

Now let's see what we get as a result of XmlSimple.xml_in(xml):

{"lane"=>[{"id"=>"1", "content"=>"unchannelized"}]}

The root is gone, because we haven't specified the KeepRoot option, but otherwise it is what we expect.

Now let's do an xml_out on it specifying the RootName option to get the root back:

<CORSIMNetwork>
  <lane id="1">unchannelized</lane>
</CORSIMNetwork>

Looks OK. I checked the AttrPrefix option, and other than requiring "@id" instead of "id" key in the input, the output is still the same.

Full script that produces correct output:

require 'xmlsimple'

lane_config = [{ "@id" => 1, "content" => "unchannelized"}]
unhappy = {
   "LaneConfig" => {"lane" => lane_config},
}

doc = XmlSimple.xml_out(unhappy, {"AttrPrefix" => true, 
                                  "RootName"   => "CORSIMNetwork",
                                  "ContentKey" => "content"
                 })
puts doc

Output:

<CORSIMNetwork>
  <LaneConfig>
    <lane id="1">unchannelized</lane>
  </LaneConfig>
</CORSIMNetwork>

Since the above works for me, the only thing I can think of is that your hash must not contain what you think it contains.

Mark Thomas
  • 37,131
  • 11
  • 74
  • 101
2

these are some examples that could help you

=begin
    <lane id="1">
        bolt,usain
    </lane>
=end

data = {'id' => 1,'content' => 'bolt,usain'}
p XmlSimple.xml_out(data,{:rootname => 'lane'})

=begin
    <lane id="1">
        <runner num="1">
            bolt, usain
        </runner>
    </lane>
=end

data = {'id' => 1, 'runner' => [{'num' => 1, 'content' => 'bolt,usain'}]}
p XmlSimple.xml_out(data,{:rootname => 'lane'})

=begin 
    <lane id="1">
        <runner num="1">
            bolt,usain
        </runner>
        <country code="165">
            jamaica
        </country>
    </lane>
=end

data = {'id' => 1, 
        'runner' => [{'num' => 1, 'content' => 'bolt, usain'}],
        'country' => [{'code' => 165, 'content' => 'jamaica'}]
        }
p XmlSimple.xml_out(data,{:rootname => 'lane'})

=begin 
    <lane id="1">
        <runner num="1">
            <surname>bolt</surname>
            <name>usain</name)
        </runner>
        <country code="165">
            jamaica
        </country>
    </lane>
=end

data = {'id' => 1,
        'runner' => [{'num' => 1, 'surname' => ["bolt"], 'name' => ["usain"]}],
        'country' => [{'code' => 165, 'content' => 'jamaica'}]
        }
p XmlSimple.xml_out(data,{:rootname => 'lane'})

first appear the xml to obtain, as a block comment, afterwards comes the xml-simple code needed to generate that xml.

pgon
  • 55
  • 1