Builder GEM XML formatting - ruby-on-rails

I'm using the Ruby Gem Builder, and I need this output..
<?xml version="1.0" encoding="utf-8"?>
<fileAttachment> "name of file here.xls"
<Data>zip</Data>
<Size>7434</Size>
</fileAttachment>
My code is below, but the file name next to "fileAttachment" just isn't working.. This is something simple I'm just not seeing it?? The error says I can't mix text with a block.. makes sense I just don't know the correct syntax.
xml = Builder::XmlMarkup.new(:indent => 2 )
xml.instruct! :xml,:version=>"1.0", :encoding => "utf-8"
xml.fileAttachment("name of file here.xls") do
xml.Data "zip"
xml.Size "7434"
end

I think you want to use the text! method:
xml.fileAttachment do
xml.text! "name of file here.xls"
xml.Data "zip"
xml.Size "7434"
end

Related

Declaring XML Tags in Ruby

I am using Ruby to pull information from an excel sheet and with this information produce an xml file. I need to produce this in Ruby:
What I want:
<Betrag waehrung="EUR">150000</Betrag>
What I have:
<Betrag waehrung ="EUR"/>
I am currently trying xml.Betrag "Waehrung": "Eur"
the Betrag has a row Identifier of "#{row[13]}" which is where it can be found on the excel sheet I am using. I have tried: xml.Betrag "Waehrung": ("Eur"), ("#{row[13]}") with no success, could you please advise?
require 'nokogiri'
builder = Nokogiri::XML::Builder.new do |xml|
xml.Betrag(waehrung: 'EUR') do |e|
e << '150000'
end
end
puts builder.to_xml
=>
<?xml version="1.0"?>
<Betrag waehrung="EUR">150000</Betrag>

ruby to_xml set root attributes

I need to convert a ruby hash to xml. Here is the hash:
hash = {
"AffiliateInfo" => {
"Username" => '123456',
"Password" => "Mypass",
"TrackingCampaign" => "MyTrackingCampaign",
"Env" => "production"
}
}
and the xml I wanted to generate:
<?xml version="1.0" encoding="UTF-8"?>
<InsuranceRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<AffiliateInfo>
<Username>12696</Username>
<Password>MyPassword</Password>
<TrackingCampaign>MyTrackingCampaign</TrackingCampaign>
<LeadSourceID>SourceID</LeadSourceID>
<ProductionEnvironment>true</ProductionEnvironment>
</AffiliateInfo>
</InsuranceRequest>
When I do:
hash.to_xml(root: 'InsuranceRequest')
I get the following xml output
<?xml version="1.0" encoding="UTF-8"?>
<InsuranceRequest>
<AffiliateInfo>
<Username>123456</Username>
<Password>Mypass</Password>
<TrackingCampaign>MyTrackingCampaign</TrackingCampaign>
<Env>production</Env>
</AffiliateInfo>
</InsuranceRequest>
The output is missing the properties of the root node attributes:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
I cannot add attributes to the root node. Is there a way to add these attributes using to_xml method?
Please suggest if there is any other means to solve my problem.
You need to use custom builder. Here is example with Nokogiri builder
require 'nokogiri'
hash = {"AffiliateInfo" => {
"Username" => '123456',
"Password" => "Mypass",
"TrackingCampaign" => "MyTrackingCampaign",
"Env" => "production"
}
}
builder = Nokogiri::XML::Builder.new do |xml|
xml.InsuranceRequest('xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema') do
xml.AffiliateInfo do
hash['AffiliateInfo'].each do |k, v|
xml.send(k, v)
end
end
end
end
builder.to_xml
This produces the following XML document
<?xml version="1.0"?>
<InsuranceRequest
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<AffiliateInfo>
<Username>123456</Username>
<Password>Mypass</Password>
<TrackingCampaign>MyTrackingCampaign</TrackingCampaign>
<Env>production</Env>
</AffiliateInfo>
</InsuranceRequest>
Please note that hash should be defined before builder
Here is Nokogiri documentation http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Builder

What can I use to generate a local XML file?

I have a project that I am working on and I do not know much about Rails or Ruby.
I need to generate an XML file from user input.
Can some direct me to any resource that can show me how to do this pretty quickly and easily?
The Nokogiri gem has a nice interface for creating XML from scratch. It's powerful while still easy to use. It's my preference:
require 'nokogiri'
builder = Nokogiri::XML::Builder.new do |xml|
xml.root {
xml.products {
xml.widget {
xml.id_ "10"
xml.name "Awesome widget"
}
}
}
end
puts builder.to_xml
Will output:
<?xml version="1.0"?>
<root>
<products>
<widget>
<id>10</id>
<name>Awesome widget</name>
</widget>
</products>
</root>
Also, Ox does this too. Here's a sample from the documenation:
require 'ox'
doc = Ox::Document.new(:version => '1.0')
top = Ox::Element.new('top')
top[:name] = 'sample'
doc << top
mid = Ox::Element.new('middle')
mid[:name] = 'second'
top << mid
bot = Ox::Element.new('bottom')
bot[:name] = 'third'
mid << bot
xml = Ox.dump(doc)
# xml =
# <top name="sample">
# <middle name="second">
# <bottom name="third"/>
# </middle>
# </top>
Nokogiri is a wrapper around libxml2.
Gemfile
gem 'nokogiri'
To generate xml simple use the Nokogiri XML Builder like this
xml = Nokogiri::XML::Builder.new { |xml|
xml.body do
xml.node1 "some string"
xml.node2 123
xml.node3 do
xml.node3_1 "another string"
end
xml.node4 "with attributes", :attribute => "some attribute"
xml.selfclosing
end
}.to_xml
The result will look like
<?xml version="1.0"?>
<body>
<node1>some string</node1>
<node2>123</node2>
<node3>
<node3_1>another string</node3_1>
</node3>
<node4 attribute="some attribute">with attributes</node4>
<selfclosing/>
</body>
Source: http://www.jakobbeyer.de/xml-with-nokogiri

Unwelcome string at start and end of XML output

I'm exporting XML directly to file, to avoid the time it takes to render to view, and it's working nicely:
controller:
def onixout
s = render_to_string(:template=>"isbns/onix.xml.builder")
send_data(s, :type=>"text/xml",:filename => "onix2.1.xml")
end
The Builder file is pretty standard:
xml.instruct!(:xml, :version => "1.0", :encoding => "utf-8")
xml.declare! :DOCTYPE, :ONIXMessage, :SYSTEM, "http://www.editeur.org/onix/2.1/03/reference/onix-international.dtd"
xml.ONIXMessage do
xml.Header do
if Company.where(:client_id => current_user.client_id).first.nil?
else
xml.FromCompany Company.where(:client_id => current_user.client_id).first.sendername
end
end
Isbn.where(:client_id => current_user.client_id).search(params[:q]).result.all.each do |isbn|
xml.Product do
xml.NotificationType isbn.notificationtype unless isbn.notificationtype.blank?
isbn.productcodes.each do |productcode|
xml.ProductIdentifier do
#more
In the resultant file, though, I'm getting an undesirable string at the start (e047d in this case):
e047d
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ONIXMessage SYSTEM "http://www.editeur.org/onix/2.1/03/reference/onix-international.dtd">
<ONIXMessage>
<Header>
#more
And there's a '0' at the end of the doc too.
Any idea what they are? And, obviously, how to get rid?

How can I change this Nokogiri code so that it returns HTML and not the content?

I have this HTML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">
<en-note><div><strong>this is note 2</strong>. it has a url.</div></en-note>
I want to extract this from it:
<div><strong>this is note 2</strong>. it has a url.</div>
At the moment, I am doing this:
html_doc.xpath('//en-note').each do |a_tag|
p a_tag.content
end
Which gets me this:
"this is note 2. it has a url."
How can I change the code so that the actual HTML is returned, not just the text?
Simply use to_s
ruby-1.9.2-p180 :010 > Nokogiri::HTML('<tag>content</tag>').xpath('//tag').first.content
=> "content"
ruby-1.9.2-p180 :004 > Nokogiri::HTML('<tag>content</tag>').xpath('//tag').to_s
=> "<tag>content</tag>"
Just use this
html_doc.at_xpath('//en-note').to_xml

Resources