Reputation: 478
I have a predefine XML template with some tags that need to be replaced. The tag values come dynamically from the front-end.
<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>AUTHOR1</author>
<title>TITLE1</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book id="bk102">
<author>AUTHOR2</author>
<title>TITLE2</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book>
</catalog>
In above example I need to replace TITLE1
, TITLE2
, AUTHOR1
, AUTHOR2
with the actual value dynamically.
What is the best way to do this? I am using Nokogiri in some Ruby code but have had no luck.
Upvotes: 0
Views: 667
Reputation: 160551
The basic idea is you need to search the XML for the <book>
tags. For each book found, retrieve the block of values that apply to it. Find the <author>
tag and replace its text. Find the <title>
tag, and replace its text also. Then go to the next book.
However, in your example, writing code to do that is overkill when a simple gsub
will do it in one pass:
xml = '<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>AUTHOR1</author>
<title>TITLE1</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book id="bk102">
<author>AUTHOR2</author>
<title>TITLE2</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book>
</catalog>
'
values = {
'TITLE1' => 'Moby Dick',
'AUTHOR1' => 'Herman Melville',
'TITLE2' => 'Tom Sawyer',
'AUTHOR2' => 'Mark Twain',
}
puts xml.gsub(Regexp.union(values.keys), values)
# >> <?xml version="1.0"?>
# >> <catalog>
# >> <book id="bk101">
# >> <author>Herman Melville</author>
# >> <title>Moby Dick</title>
# >> <genre>Computer</genre>
# >> <price>44.95</price>
# >> <publish_date>2000-10-01</publish_date>
# >> <description>An in-depth look at creating applications
# >> with XML.</description>
# >> </book>
# >> <book id="bk102">
# >> <author>Mark Twain</author>
# >> <title>Tom Sawyer</title>
# >> <genre>Fantasy</genre>
# >> <price>5.95</price>
# >> <publish_date>2000-12-16</publish_date>
# >> <description>A former architect battles corporate zombies,
# >> an evil sorceress, and her own childhood to become queen
# >> of the world.</description>
# >> </book>
# >> </catalog>
This use of gsub
isn't used often, but I've used it many times when substituting values into templates. Using tags/keys that are guaranteed to be unique in the document are essential, so I often flag them using leading and trailing double underscores. In other words __TITLE1__
, __AUTHOR1__
, etc.
Doing this you can easily replace the content of the other fields, such as <genre>
, <price>
, etc.
Name the variables in the form the same as the keys/tags, and the task becomes even easier because you should receive a hash of field-names and field-values, which becomes the source for your hash used in the gsub
.
Be sure to verify/sanitize the values before substituting. Users mistype and malicious ones can deliberately enter data in an attempt to break your code, or worse, whatever the XML is fed into.
Upvotes: 1