Set Tag Attribute and Add Plain Text Content to the Tag Using Nokogiri Builder (Ruby)

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



Leave a reply



Submit