1

The Earlier solution provided by @Jamie seems to be working fine for only few scenario's. The solution is

require 'nokogiri'
require 'ostruct'

xml = <<-'XML'
<Catalog>
    <Interface></Interface>
        <Dialog></Dialog>
        <Manifest></Manifest>
</Catalog>
XML

collection = [
    OpenStruct.new(book: '1984', pen: 'George Orwell'),
    OpenStruct.new(book: 'Thinking, Fash and Slow', pen: 'Daniel Kahneman')
]

doc = Nokogiri::XML(xml) 
catalog = doc.root

node_set = Nokogiri::XML::NodeSet.new(doc)
collection.each do |object|
    book = Nokogiri::XML::Node.new('Book', doc)
    book_author = Nokogiri::XML::Node.new('Book_Author', doc)

    book.content = object.book
    book_author.content = object.pen

    node_set << book
    node_set << book_author
end

catalog.first_element_child.before(node_set)

puts doc.to_xml    

While I have the below XML to be constructed using Nokogiri. I just wanted to know, if this can't be done using OpenStruct. Could this be done using Json? If Yes, Can you please suggest me how to construct this using Nokogiri and Json.

Below is this XML, I want to construct...

<CatalogOrder>
        <CatalogStoreNumber>657758</CatalogStoreNumber>
        <CatalogStoreId>CTH6536</CatalogStoreId>
        <CatalogStoreLocation>UnitedStates</CatalogStoreLocation>
        <CatalogOwnerId>TYCT11190</CatalogOwnerId>
        <CatalogOwner>McGrawHill Pub.</CatalogOwner>
        <CatalogList>
            <CatalogProductInfo>
                <ProductType>Book</ProductType>
                <ProductName>The Client</ProductName>                          
                <ProductId>CRSUS113246A</ProductId>
                <ProductCategory>Crime And Suspense</ProductCategory>
                <ProductSubCategory>Vintage Books</ProductSubCategory>
                <ProductPrice>45.50 USD</ProductPrice>
                <ProductAuthor>
                        <AuthorFirstName>John Grisham</AuthorFirstName>
                    <AuthorMiddleName>Willbur</AuthorMiddleName>
                    <AuthorContact>19876648981</AuthorContact>
                </ProductAuthor>
            </CatalogProductInfo>
            <CatalogProductInfo>
                <ProductType>Pen</ProductType>
                <ProductName>Reynolds</ProductName>                        
                <ProductId>PRREY546647</ProductId>
                <ProductCategory>Misc. Stationary</ProductCategory>
                <ProductSubCategory>Stationary Items</ProductSubCategory>
                <ProductPrice>3.00 USD</ProductPrice>
                <ProductAuthor>
                    <AuthorFirstName>Ryan Reynolds</AuthorFirstName>
                    <AuthorMiddleName>William</AuthorMiddleName>
                    <AuthorContact>16577589898</AuthorContact>
                </ProductAuthor>
            </CatalogProductInfo>
            <CatalogListType>ProductCollection</CatalogListType>
            <CatalogListSource>Web</CatalogListSource>
    </CatalogList>
    <CatalogVerificationLog>
            <CatalogVerificationStatus>Verified</CatalogVerificationStatus>
            <CatalogVerificationDateTime>2012-03-12T13:00:15+5:30</CatalogVerificationDateTime>
            <CatalogVerificationId>64774A</CatalogVerificationId>
            <CatalogVerificationRequestedBy>User_121</CatalogVerificationRequestedBy>
    </CatalogVerificationLog>
    </CatalogOrder>

I have data that is organized in OpenStruct format below...

require 'ostruct'
require 'nokogiri'

collection = [
OpenStruct.new(:catalogStoreNumber => '657758',
:catalogStoreId => 'CTH6536',
:catalogStoreLocation => 'UnitedStates', 
:catalogOwnerId => 'TYCT11190',
:catalogOwner => 'McGrawHill Pub.',
:catalogList => OpenStruct.new(
    :catalogProductInfo => OpenStruct.new(
        :productType => 'Book',
        :productName => 'The Client',
    :productId => 'CRSUS113246A',
        :productCategory => 'Crime And Suspense',
        :productSubcategory => 'Vintage Books',  
        :productPrice => '45.50 USD',
        :productAuthor => OpenStruct.new(
                :authorFirstName =>'John Grisham',
            :authorMiddleName=> 'Willburt',
            :authorContact => '19876648981')),
:catalogProductInfo => OpenStruct.new(
        :productType => 'Pen',
        :productName => 'Reynolds',
        :productId => 'PRREY546647',
        :productCategory => 'Misc. Stationary',
        :productSubcategory => 'Stationery Items',  
        :productPrice => '3.00 USD',
        :productManufacturer => 'Reynolds Inc.',
        :productAuthor => OpenStruct.new(
            :authorFirstName => 'Ryan Reynolds',
            :authorMiddleName => 'William',
            :authorContact => '16577589898')),
:catalogListType => 'ProductCollection',
:catalogListSource => 'Web'
),
:catalogVerificaitionLog => OpenStruct.new(
        :catalogVerificationStatus => 'Verified',
    :catalogVerificationDateTime => '2012-03-12T13:00:15+5:30',
    :catalogVerificationId => '64774A',
    :catalogVerificationRequestedBy => 'user_121')
)]

I am not sure whether it is possible with OpenStruct, as it lacks Nesting capabilities. Is there any other Way to use JSon to achieve this without any outstanding limitations ? Please correct my earlier code.

To see this earlier question, How to Add child Nodes in NodeSet using Nokogiri Click [here] (http://stackoverflow.com/questions/10300095/how-to-add-child-nodes-in-nodeset-using-nokogiri)

I see below issues with OpenStruct...

i want to access the "productType" of first "catalogProductInfo" and i said "collection.catalogList.catalogProductInfo.productType.content" and I get the below error

"undefined method `productType' for # (NoMethodError)

I got stuck here and want to get out if this situation. If data can't be organized using OpenStruct. Can this be done using JSon. ? Also suggest me the way to do it Nokogiri and JSon. Help me out.

user1023627
  • 183
  • 1
  • 3
  • 12
  • What do you mean when you say that openstruct lacks nesting? – Frederick Cheung Jun 24 '12 at 14:23
  • I tried to access the "productType" element in the above collection of OpenStruct elements .. The code collection.catallogList.catalogProductInfo.productType.content Gives me below error .. "undefined method `productType' for # (NoMethodError). How do i access an OpenStruct element which is nested ? Please suggest me – user1023627 Jun 24 '12 at 16:08
  • You'd have to do `collection[0].catalogList.catalogProductInfo.productType` - it doesn't know which element from that array you want to use. – Frederick Cheung Jun 24 '12 at 16:13
  • Thanks @Fredrick, I also want to know which way of organizing data would be scalable. I don't want to use ".yml" though. Can this be done using Json ? – user1023627 Jun 24 '12 at 20:58

0 Answers0