set tag attribute and add plain text content to the tag using nokogiri builder (ruby)
There are two approaches you can use.
Using .text
You can call the .text
method to set the text of a node:
builder = Nokogiri::XML::Builder.new { |xml|
xml.Transaction("requestName" => "OrderRequest") do
xml.Option("b" => "hive"){ xml.text("hello") }
end
}
which produces:
<?xml version="1.0"?>
<Transaction requestName="OrderRequest">
<Option b="hive">hello</Option>
</Transaction>
Solution using text parameter
Alternatively, you can pass the text in as a parameter. The text should be passed in before the attribute values. In other words, the tag is added in the form:
tag "text", :attribute => 'value'
In this case, the desired builder would be:
builder = Nokogiri::XML::Builder.new { |xml|
xml.Transaction("requestName" => "OrderRequest") do
xml.Option("hello", "b" => "hive")
end
}
Produces the same XML:
<?xml version="1.0"?>
<Transaction requestName="OrderRequest">
<Option b="hive">hello</Option>
</Transaction>
How to add an attribute to Nokogiri XML builder?
Add the attributes to the node like this
xml = Nokogiri::XML::Builder.new do |x|
x.root do
x.book(isbn: 1235) do
x.text('Don Quixot')
end
end
end.doc
Or, after re-rereading your question perhaps you wanted to add it to the parent further in the do block. In that case, this works:
xml = Nokogiri::XML::Builder.new do |x|
x.root do
x.book do
x.parent.set_attribute('isbn', 12345)
x.text('Don Quixot')
end
end
end.doc
Generates:
<?xml version="1.0"?>
<root>
<book isbn="1235">Don Quixot</book>
</root>
XML generation using Nokogiri involving nested tags and namespace
You only need 1 builder:
env_ns = {
"xmlns:env" => "http://abc.ca"
}
mm7_ns = {
"xmlns:mm7" => "http://def.ca"
}
builder = Nokogiri::XML::Builder.new do |xml|
xml['env'].Envelope(env_ns) do
xml.Header do
xml['mm7'].TransactionID(mm7_ns, "Some Text Here")
end
end
end
puts builder.to_xml
# will render the following:
# <?xml version="1.0"?>
# <env:Envelope xmlns:env="http://abc.ca">
# <env:Header>
# <mm7:TransactionID xmlns:mm7="http://def.ca">Some Text Here</mm7:TransactionID>
# </env:Header>
# </env:Envelope>
How do I create this element using Nokogiri builder?
Not sure if this is what you are asking, but you can use the builder text
method to create a text element inside another:
xml.SearchCondition('expressionLanguage' => 'String', 'expressionType' => 'PartyNumber') {
xml.text "31955854"
}
You're not using the namespace in your example, but you don't mention that, so I guess that is not an issue.
Building blank XML tags with Nokogiri?
SaveOptions::NO_EMPTY_TAGS will get you what you want.
require 'nokogiri'
builder = Nokogiri::XML::Builder.new do |xml|
xml.blah(nil)
end
puts 'broken:'
puts builder.to_xml
puts 'fixed:'
puts builder.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS)
output:
(511)-> ruby derp.rb
broken:
<?xml version="1.0"?>
<blah/>
fixed:
<?xml version="1.0"?>
<blah></blah>
How can I generate a dynamic tag with Nokogiri::XML::Builder?
Try the following. I added a root node as Nokogiri requires one if I'm not mistaken.
builder = Nokogiri::XML::Builder.new do |xml|
xml.root do |root|
for tag in tags
xml.send(tag, someval)
end
end
end
Add elements to Nokogiri XML Builder outside of nesting
Bumped into this two years after the fact, and thought the accepted answer was way more convoluted than it needs to be.
The problem is, you're building an XML fragment here, while by default Nokogiri's builder assumes you're building a complete document. XML documents only have one root node.
One option would be to build the complete document as follows, then grab the root's children:
<DISPOSABLE_OUTER_NODE>
<Data>
<Groups>
<GroupType>test</GroupType>
</Groups>
</Data>
<AnotherNode>13</AnotherNode>
</DISPOSABLE_OUTER_NODE>
But there's a better, "fragmentary" way. You build an empty fragment, then have builder work on that rather than a new document:
frag = Nokogiri::XML::DocumentFragment.parse("")
Nokogiri::XML::Builder.with( frag ){ |b|
b.Data do
b.Groups do
b.GroupType "test"
end
end
b.AnotherNode "13"
}
puts frag.to_xml
Then just stick it into whatever document you're modifying.
Maybe with
is a latecomer to Nokogiri. But it's an elegant solution to a problem I was having, so I thought it belonged here.
Related Topics
Ruby Select and Reject in One Method
Wicked-Pdf Not Showing Images, 'Wicked_Pdf_Image_Tag' Undefined
How to Set Custom User-Agent for Mechanize in Rails
Write a Migration with Reference to a Model Twice
How to Enter Password in a Popup Using Watir
Ruby Operator Overloading Question
List Dynamic Attributes in a Mongoid Model
Single Occurrence Event with Ice_Cube Gem Using Start_Time and End_Time
How to Tell If I'm Running from Jruby VS. Ruby
How to Push Keys and Values into an Empty Hash W/ Ruby
Rails 4 Strong Parameters Without Required Parameters
How to Get Rspec to Run All Tests Nested Under a Folder
How to Print Something Without a New Line in Ruby
In Ruby What's the Difference Between Self.Method and a Method Within Class << Self
How to Select Array Elements in a Given Range in Ruby
How to Stop God from Leaving Stale Resque Worker Processes
How to Resolve Deprecation Warnings for Openssl::Cipher::Cipher#Encrypt