set tag attribute and add plain text content to the tag using nokogiri builder (ruby)
Asked Answered
P

1

17

I am trying to build XML using Nokogiri with some tags that have both attributes and plain text inside the tag. So I am trying to get to this:

<?xml version="1.0"?>
<Transaction requestName="OrderRequest">
  <Option b="hive">hello</Option>
</Transaction>

Using builder I have this:

builder = Nokogiri::XML::Builder.new { |xml|
  xml.Transaction("requestName" => "OrderRequest") do
    xml.Option("b" => "hive").text("hello")
  end
}

which renders to:

<Transaction requestName="OrderRequest">
  <Option b="hive" class="text">hello</Option>
</Transaction>

So it produces <Option b="hive" class="text">hello</Option> where I would just like it to be <Option b="hive">hello</Option>

I am not sure how to do that. If I try to get a Nokogiri object by just feeding it the XML I want, it renders back exactly what I need with the internal text being within the <Option> tag set to children=[#<Nokogiri::XML::Text:0x80b9e3dc "hello">] and I don't know how to set that from builder.

If anyone has a reference to that in the Nokogiri documentation, I would appreciate it.

Persimmon answered 25/4, 2013 at 15:51 Comment(0)
V
39

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>
Verticillaster answered 25/4, 2013 at 16:57 Comment(2)
It looks like the second answer no longer works, at least for me in Nokogiri 1.81. The first answer using a block still seems to be fine.Baryton
@MarkWeston, it still works for Nokogiri v1.10.7 (currently the latest). Maybe there is a bug in v1.8.1?Verticillaster

© 2022 - 2024 — McMap. All rights reserved.