Add a dtd using nokogiri builder
Asked Answered
T

5

5

I am using nokogiri to generate svg pictures. I would like to add the correct xml preamble and svg DTD declaration to get something like:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg>
...

With builder I could use instruct! and declare! but I want to stick with nokogiri because I use it for other purpose in my project and I want to stay low on requirements. Do you have some ideas ?

Thanks

Tramp answered 25/12, 2009 at 16:39 Comment(0)
Q
2

You can now (don't know from which version) use Node#create_internal_subset to create the DTD node. For more info see: http://nokogiri.org/Nokogiri/XML/Builder.html

And scroll down to the "Document Types" section for an example.

Quotation answered 22/6, 2010 at 14:29 Comment(2)
The link is dead :/Pogy
rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/BuilderAlveolus
R
5

Following is from a note at the bottom of the Nokogiri::XML::Builder page (maybe added recently), which I think will do the trick:

builder = Nokogiri::XML::Builder.new do |xml|
  xml.doc.create_internal_subset(
    'html',
    "-//W3C//DTD HTML 4.01 Transitional//EN",
    "http://www.w3.org/TR/html4/loose.dtd"
  )
  xml.root do
    xml.foo
  end
end

puts builder.to_xml
Rondeau answered 6/8, 2010 at 18:21 Comment(0)
Q
2

You can now (don't know from which version) use Node#create_internal_subset to create the DTD node. For more info see: http://nokogiri.org/Nokogiri/XML/Builder.html

And scroll down to the "Document Types" section for an example.

Quotation answered 22/6, 2010 at 14:29 Comment(2)
The link is dead :/Pogy
rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/BuilderAlveolus
T
1

Here is a possible solution, though it looks like a dirty trick:

#1. I build the svg document
builder = Nokogiri::XML::Builder.new do |xml|
  xml.svg do
    # ...
  end
end

#2. I retrieve the svg root node
svg = builder.doc.xpath("/svg").first

#3. I define and parse an xml document with the required preamble and dtd
str =<<EOS
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1. /DTD/svg11.dtd">
EOS
doc = Nokogiri::XML::Document.parse(str)

#4. I add the svg node to the document above
doc.add_child(svg)
Tramp answered 29/12, 2009 at 16:24 Comment(0)
N
1

For those working with HTML, Eric Walkers' example doesn't quite work since a doctype is automatically added. You need to remove it first:

builder = Nokogiri::HTML::Builder.new do |html|
  html.doc.internal_subset.remove
  html.doc.create_internal_subset('html', nil, nil)
end

This will add the HTML5 doctype a.k.a. <!DOCTYPE html>

Nanine answered 31/3, 2017 at 7:39 Comment(0)
N
0

There does not appear to be any way to add a doctype using Nokogiri::XML::Builder. However, adding a doctype declaration to an XML document is of dubious utility, unless your tools require it. Read DTDs Don't Work on the Web by Henri Sivonen for some reasons why it's not a very good idea to use DTDs, and you should instead ensure your document is well-formed, and validate it against an external schema (which may be a DTD, or may be something more powerful like XSD or RELAX-NG) rather than a DTD embedded within the document.

Notify answered 25/12, 2009 at 20:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.