libxml-ruby-3.2.1/0000755000004100000410000000000013760147770014027 5ustar www-datawww-datalibxml-ruby-3.2.1/test/0000755000004100000410000000000013760147770015006 5ustar www-datawww-datalibxml-ruby-3.2.1/test/test_node_edit.rb0000644000004100000410000001117013760147770020324 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class TestNodeEdit < Minitest::Test def setup xp = LibXML::XML::Parser.string('onetwothree') @doc = xp.parse end def teardown @doc = nil end def first_node @doc.root.child end def second_node first_node.next end def third_node second_node.next end def test_add_next_01 first_node.next = LibXML::XML::Node.new('num', 'one-and-a-half') assert_equal('oneone-and-a-halftwothree', @doc.root.to_s.gsub(/\n\s*/,'')) end def test_add_next_02 second_node.next = LibXML::XML::Node.new('num', 'two-and-a-half') assert_equal('onetwotwo-and-a-halfthree', @doc.root.to_s.gsub(/\n\s*/,'')) end def test_add_next_03 third_node.next = LibXML::XML::Node.new('num', 'four') assert_equal 'onetwothreefour', @doc.root.to_s.gsub(/\n\s*/,'') end def test_add_prev_01 first_node.prev = LibXML::XML::Node.new('num', 'half') assert_equal 'halfonetwothree', @doc.root.to_s.gsub(/\n\s*/,'') end def test_add_prev_02 second_node.prev = LibXML::XML::Node.new('num', 'one-and-a-half') assert_equal 'oneone-and-a-halftwothree', @doc.root.to_s.gsub(/\n\s*/,'') end def test_add_prev_03 third_node.prev = LibXML::XML::Node.new('num', 'two-and-a-half') assert_equal 'onetwotwo-and-a-halfthree', @doc.root.to_s.gsub(/\n\s*/,'') end def test_remove_node first_node.remove! assert_equal('twothree', @doc.root.to_s.gsub(/\n\s*/,'')) end def test_remove_node_gc xp = LibXML::XML::Parser.string('onetwothree') doc = xp.parse doc.root.child.remove! GC.start refute_nil(doc) end def test_remove_node_iteration nodes = Array.new @doc.root.each_element do |node| if node.name == 'num' nodes << node node.remove! end end assert_equal(3, nodes.length) end def test_reuse_removed_node # Remove the node node = @doc.root.first.remove! refute_nil(node) # Add it to the end of the document @doc.root.last.next = node assert_equal('twothreeone', @doc.root.to_s.gsub(/\n\s*/,'')) end def test_append_existing_node doc = LibXML::XML::Parser.string('abfirstsecondcd').parse node1 = doc.find_first('//two') doc.root << node1 assert_equal('abfirstcdsecond', doc.root.to_s) end def test_wrong_doc doc1 = LibXML::XML::Parser.string('').parse doc2 = LibXML::XML::Parser.string('').parse node = doc1.root.child error = assert_raises(LibXML::XML::Error) do doc2.root << node end GC.start assert_equal(' Nodes belong to different documents. You must first import the node by calling LibXML::XML::Document.import.', error.to_s) end # This test is to verify that an earlier reported bug has been fixed def test_merge documents = [] # Read in 500 documents 500.times do documents << LibXML::XML::Parser.string(File.read(File.join(File.dirname(__FILE__), 'model', 'merge_bug_data.xml'))).parse end master_doc = documents.shift documents.each do |child_doc| master_body = master_doc.find("//body").first child_body = child_doc.find("//body").first child_element = child_body.detect do |node| node.element? end master_body << child_element.copy(true) end end def test_append_chain node = LibXML::XML::Node.new('foo') << LibXML::XML::Node.new('bar') << "bars contents" assert_equal('bars contents', node.to_s) end def test_set_base @doc.root.base_uri = 'http://www.rubynet.org/' assert_equal("\n one\n two\n three\n", @doc.root.to_s) end end libxml-ruby-3.2.1/test/test_node_xlink.rb0000644000004100000410000000143513760147770020527 0ustar www-datawww-data# encoding: UTF-8 # $Id$ require_relative './test_helper' class TC_XML_Node_XLink < Minitest::Test def setup() xp = LibXML::XML::Parser.string('one') doc = xp.parse assert_instance_of(LibXML::XML::Document, doc) @root = doc.root assert_instance_of(LibXML::XML::Node, @root) end def teardown() @root = nil end def test_xml_node_xlink() for elem in @root.find('fixnum') assert_instance_of(LibXML::XML::Node, elem) assert_instance_of(TrueClass, elem.xlink?) assert_equal("simple", elem.xlink_type_name) assert_equal(LibXML::XML::Node::XLINK_TYPE_SIMPLE, elem.xlink_type) end end end libxml-ruby-3.2.1/test/test_namespaces.rb0000644000004100000410000001666313760147770020525 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class TestNamespaces < Minitest::Test def setup file = File.join(File.dirname(__FILE__), 'model/soap.xml') @doc = LibXML::XML::Document.file(file) end def teardown @doc = nil end def test_namespace_node node = @doc.root ns = node.namespaces.namespace assert_equal('soap', ns.prefix) assert_equal('http://schemas.xmlsoap.org/soap/envelope/', ns.href) end def test_namespace_attr node = @doc.root attr = node.attributes.get_attribute('encodingStyle') assert_equal('soap', attr.ns.prefix) assert_equal('soap', attr.namespaces.namespace.prefix) end def test_set_namespace_node node = LibXML::XML::Node.new('Envelope') assert_equal('', node.to_s) ns = LibXML::XML::Namespace.new(node, 'soap', 'http://schemas.xmlsoap.org/soap/envelope/') assert_equal("", node.to_s) assert_nil(node.namespaces.namespace) # Now put the node in the soap namespace node.namespaces.namespace = ns refute_nil(node.namespaces.namespace) assert_equal("", node.to_s) end def test_set_namespace_attribute # Create node node = LibXML::XML::Node.new('Envelope') assert_equal('', node.to_s) # Create attribute attr = LibXML::XML::Attr.new(node, "encodingStyle", "http://www.w3.org/2001/12/soap-encoding") assert_equal('', node.to_s) # Create namespace attribute ns = LibXML::XML::Namespace.new(node, 'soap', 'http://schemas.xmlsoap.org/soap/envelope/') assert_equal('', node.to_s) assert_nil(node.namespaces.namespace) # Now put the node in the soap namespace node.namespaces.namespace = ns refute_nil(node.namespaces.namespace) assert_equal('', node.to_s) # Now put the attribute in the soap namespace attr.namespaces.namespace = ns refute_nil(node.namespaces.namespace) assert_equal('', node.to_s) end def test_define_namespace node = LibXML::XML::Node.new('Envelope') assert_equal('', node.to_s) LibXML::XML::Namespace.new(node, 'soap', 'http://schemas.xmlsoap.org/soap/envelope/') assert_equal("", node.to_s) assert_nil(node.namespaces.namespace) end def test_define_default_namespace node = LibXML::XML::Node.new('Envelope') assert_equal('', node.to_s) LibXML::XML::Namespace.new(node, nil, 'http://schemas.xmlsoap.org/soap/envelope/') assert_equal("", node.to_s) # This seems wrong, but appears to be the way libxml works assert_nil(node.namespaces.namespace) end def test_namespaces node = @doc.find_first('//ns1:IdAndName', :ns1 => 'http://domain.somewhere.com') namespaces = node.namespaces.sort assert_equal(5, namespaces.length) namespace = namespaces[0] assert_instance_of(LibXML::XML::Namespace, namespace) assert_nil(namespace.prefix) assert_equal('http://services.somewhere.com', namespace.href) namespace = namespaces[1] assert_instance_of(LibXML::XML::Namespace, namespace) assert_equal('ns1', namespace.prefix) assert_equal('http://domain.somewhere.com', namespace.href) namespace = namespaces[2] assert_instance_of(LibXML::XML::Namespace, namespace) assert_equal('soap', namespace.prefix) assert_equal('http://schemas.xmlsoap.org/soap/envelope/', namespace.href) namespace = namespaces[3] assert_instance_of(LibXML::XML::Namespace, namespace) assert_equal('xsd', namespace.prefix) assert_equal('http://www.w3.org/2001/XMLSchema', namespace.href) namespace = namespaces[4] assert_instance_of(LibXML::XML::Namespace, namespace) assert_equal('xsi', namespace.prefix) assert_equal('http://www.w3.org/2001/XMLSchema-instance', namespace.href) end def test_namespace_definitions ns_defs = @doc.root.namespaces.definitions assert_equal(3, ns_defs.size) namespace = ns_defs[0] assert_instance_of(LibXML::XML::Namespace, namespace) assert_equal('soap', namespace.prefix) assert_equal('http://schemas.xmlsoap.org/soap/envelope/', namespace.href) namespace = ns_defs[1] assert_instance_of(LibXML::XML::Namespace, namespace) assert_equal('xsd', namespace.prefix) assert_equal('http://www.w3.org/2001/XMLSchema', namespace.href) namespace = ns_defs[2] assert_instance_of(LibXML::XML::Namespace, namespace) assert_equal('xsi', namespace.prefix) assert_equal('http://www.w3.org/2001/XMLSchema-instance', namespace.href) node = @doc.root.find_first('//ns:getManufacturerNamesResponse', :ns => 'http://services.somewhere.com') ns_defs = node.namespaces.definitions assert_equal(1, ns_defs.size) namespace = ns_defs[0] assert_instance_of(LibXML::XML::Namespace, namespace) assert_nil(namespace.prefix) assert_equal('http://services.somewhere.com', namespace.href) end def test_find_by_prefix namespace = @doc.root.namespaces.find_by_prefix('soap') assert_instance_of(LibXML::XML::Namespace, namespace) assert_equal('soap', namespace.prefix) assert_equal('http://schemas.xmlsoap.org/soap/envelope/', namespace.href) end def test_find_default_ns namespace = @doc.root.namespaces.find_by_prefix(nil) assert_nil(namespace) node = @doc.find_first('//ns1:getManufacturerNamesResponse', :ns1 => 'http://services.somewhere.com') namespace = node.namespaces.find_by_prefix(nil) assert_instance_of(LibXML::XML::Namespace, namespace) assert_nil(namespace.prefix) assert_equal('http://services.somewhere.com', namespace.href) end def test_find_ns_by_href node = @doc.find_first('//ns1:getManufacturerNamesResponse', :ns1 => 'http://services.somewhere.com') namespace = node.namespaces.find_by_href('http://schemas.xmlsoap.org/soap/envelope/') assert_instance_of(LibXML::XML::Namespace, namespace) assert_equal('soap', namespace.prefix) assert_equal('http://schemas.xmlsoap.org/soap/envelope/', namespace.href) end def test_default_namespace doc = LibXML::XML::Document.string('') ns = doc.root.namespaces.default assert_equal(ns.href, 'http://schemas.xmlsoap.org/soap/envelope/') end def test_default_prefix doc = LibXML::XML::Document.string('') doc.root.namespaces.default_prefix = 'soap' node = doc.root.find_first('/soap:Envelope') refute_nil(node) end end libxml-ruby-3.2.1/test/test_sax_parser.rb0000644000004100000410000002560413760147770020550 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' require 'stringio' class DocTypeCallback include LibXML::XML::SaxParser::Callbacks def on_start_element(element, attributes) end end class TestCaseCallbacks include LibXML::XML::SaxParser::Callbacks attr_accessor :result def initialize @result = Array.new end def on_cdata_block(cdata) @result << "cdata: #{cdata}" end def on_characters(chars) @result << "characters: #{chars}" end def on_comment(text) @result << "comment: #{text}" end def on_end_document @result << "end_document" end def on_end_element(name) @result << "end_element: #{name}" end def on_end_element_ns(name, prefix, uri) @result << "end_element_ns #{name}, prefix: #{prefix}, uri: #{uri}" end # Called for parser errors. def on_error(error) @result << "error: #{error}" end def on_processing_instruction(target, data) @result << "pi: #{target} #{data}" end def on_start_document @result << "startdoc" end def on_start_element(name, attributes) attributes ||= Hash.new @result << "start_element: #{name}, attr: #{attributes.inspect}" end def on_start_element_ns(name, attributes, prefix, uri, namespaces) attributes ||= Hash.new namespaces ||= Hash.new @result << "start_element_ns: #{name}, attr: #{attributes.inspect}, prefix: #{prefix}, uri: #{uri}, ns: #{namespaces.inspect}" end end class TestSaxParser < Minitest::Test def saxtest_file File.join(File.dirname(__FILE__), 'model/atom.xml') end def verify(parser) result = parser.callbacks.result i = -1 assert_equal("startdoc", result[i+=1]) assert_equal("pi: xml-stylesheet type=\"text/xsl\" href=\"my_stylesheet.xsl\"", result[i+=1]) assert_equal("start_element: feed, attr: {}", result[i+=1]) assert_equal("start_element_ns: feed, attr: {}, prefix: , uri: http://www.w3.org/2005/Atom, ns: {nil=>\"http://www.w3.org/2005/Atom\"}", result[i+=1]) assert_equal("characters: \n ", result[i+=1]) assert_equal("comment: Not a valid atom entry ", result[i+=1]) assert_equal("characters: \n ", result[i+=1]) assert_equal("start_element: entry, attr: {}", result[i+=1]) assert_equal("start_element_ns: entry, attr: {}, prefix: , uri: http://www.w3.org/2005/Atom, ns: {}", result[i+=1]) assert_equal("characters: \n ", result[i+=1]) assert_equal("start_element: title, attr: {\"type\"=>\"html\"}", result[i+=1]) assert_equal("start_element_ns: title, attr: {\"type\"=>\"html\"}, prefix: , uri: http://www.w3.org/2005/Atom, ns: {}", result[i+=1]) assert_equal("cdata: <>", result[i+=1]) assert_equal("end_element: title", result[i+=1]) assert_equal("end_element_ns title, prefix: , uri: http://www.w3.org/2005/Atom", result[i+=1]) assert_equal("characters: \n ", result[i+=1]) assert_equal("start_element: content, attr: {\"type\"=>\"xhtml\"}", result[i+=1]) assert_equal("start_element_ns: content, attr: {\"type\"=>\"xhtml\"}, prefix: , uri: http://www.w3.org/2005/Atom, ns: {}", result[i+=1]) assert_equal("characters: \n ", result[i+=1]) assert_equal("start_element: xhtml:div, attr: {}", result[i+=1]) assert_equal("start_element_ns: div, attr: {}, prefix: xhtml, uri: http://www.w3.org/1999/xhtml, ns: {\"xhtml\"=>\"http://www.w3.org/1999/xhtml\"}", result[i+=1]) assert_equal("characters: \n ", result[i+=1]) assert_equal("start_element: xhtml:p, attr: {}", result[i+=1]) assert_equal("start_element_ns: p, attr: {}, prefix: xhtml, uri: http://www.w3.org/1999/xhtml, ns: {}", result[i+=1]) assert_equal("characters: hi there", result[i+=1]) assert_equal("end_element: xhtml:p", result[i+=1]) assert_equal("end_element_ns p, prefix: xhtml, uri: http://www.w3.org/1999/xhtml", result[i+=1]) assert_equal("characters: \n ", result[i+=1]) assert_equal("end_element: xhtml:div", result[i+=1]) assert_equal("end_element_ns div, prefix: xhtml, uri: http://www.w3.org/1999/xhtml", result[i+=1]) assert_equal("characters: \n ", result[i+=1]) assert_equal("end_element: content", result[i+=1]) assert_equal("end_element_ns content, prefix: , uri: http://www.w3.org/2005/Atom", result[i+=1]) assert_equal("characters: \n ", result[i+=1]) assert_equal("end_element: entry", result[i+=1]) assert_equal("end_element_ns entry, prefix: , uri: http://www.w3.org/2005/Atom", result[i+=1]) assert_equal("characters: \n", result[i+=1]) assert_equal("end_element: feed", result[i+=1]) assert_equal("end_element_ns feed, prefix: , uri: http://www.w3.org/2005/Atom", result[i+=1]) assert_equal("end_document", result[i+=1]) end def test_file parser = LibXML::XML::SaxParser.file(saxtest_file) parser.callbacks = TestCaseCallbacks.new parser.parse verify(parser) end def test_file_no_callbacks parser = LibXML::XML::SaxParser.file(saxtest_file) assert_equal true, parser.parse end def test_noexistent_file error = assert_raises(LibXML::XML::Error) do LibXML::XML::SaxParser.file('i_dont_exist.xml') end assert_equal('Warning: failed to load external entity "i_dont_exist.xml".', error.to_s) end def test_nil_file error = assert_raises(TypeError) do LibXML::XML::SaxParser.file(nil) end assert_match(/nil into String/, error.to_s) end def test_io File.open(saxtest_file) do |file| parser = LibXML::XML::SaxParser.io(file) parser.callbacks = TestCaseCallbacks.new parser.parse verify(parser) end end def test_nil_io error = assert_raises(TypeError) do LibXML::XML::HTMLParser.io(nil) end assert_equal("Must pass in an IO object", error.to_s) end def test_string_no_callbacks xml = File.read(saxtest_file) parser = LibXML::XML::SaxParser.string(xml) assert_equal true, parser.parse end def test_string xml = File.read(saxtest_file) parser = LibXML::XML::SaxParser.string(xml) parser.callbacks = TestCaseCallbacks.new parser.parse verify(parser) end def test_string_io xml = File.read(saxtest_file) io = StringIO.new(xml) parser = LibXML::XML::SaxParser.io(io) parser.callbacks = TestCaseCallbacks.new parser.parse verify(parser) end def test_nil_string error = assert_raises(TypeError) do LibXML::XML::SaxParser.string(nil) end assert_equal("wrong argument type nil (expected String)", error.to_s) end def test_doctype xml = <<-EOS a1 EOS parser = LibXML::XML::SaxParser.string(xml) parser.callbacks = DocTypeCallback.new doc = parser.parse refute_nil(doc) end def test_parse_warning # Two xml PIs is a warning xml = <<-EOS EOS parser = LibXML::XML::SaxParser.string(xml) parser.callbacks = TestCaseCallbacks.new parser.parse # Check callbacks result = parser.callbacks.result i = -1 assert_equal("startdoc", result[i+=1]) assert_equal("error: Warning: xmlParsePITarget: invalid name prefix 'xml' at :2.", result[i+=1]) assert_equal("pi: xml-invalid ", result[i+=1]) assert_equal("start_element: Test, attr: {}", result[i+=1]) assert_equal("start_element_ns: Test, attr: {}, prefix: , uri: , ns: {}", result[i+=1]) assert_equal("end_element: Test", result[i+=1]) assert_equal("end_element_ns Test, prefix: , uri: ", result[i+=1]) assert_equal("end_document", result[i+=1]) end def test_parse_error xml = <<-EOS EOS parser = LibXML::XML::SaxParser.string(xml) parser.callbacks = TestCaseCallbacks.new error = assert_raises(LibXML::XML::Error) do parser.parse end # Check callbacks result = parser.callbacks.result i = -1 assert_equal("startdoc", result[i+=1]) assert_equal("start_element: Results, attr: {}", result[i+=1]) assert_equal("start_element_ns: Results, attr: {}, prefix: , uri: , ns: {}", result[i+=1]) assert_equal("characters: \n", result[i+=1]) assert_equal("error: Fatal error: EndTag: ' AQUALIA THERMAL Lichte cr├иme - Versterkende & kalmerende 24 u hydraterende verzorging
Huid wordt continu gehydrateerd, intens versterkt en gekalmeerd.
Hypoallergeen. Geschikt voor de gevoelige huid.

01.EFFECTIVITEIT
Intensief gehydrateerd, de huid voelt gekalmeerd. Ze voelt de hele dag soepel en fluweelzacht aan, zonder een trekkerig gevoel. De huid is elastischer, soepeler en stralender. Doeltreffendheid getest onder dermatologisch toezicht.

02.GEBRUIK
's Morgens en/ of 's avonds aanbrengen.

03.ACTIEVE INGREDIENTEN
Technologische innovatie: 24 u continue cellulaire vochtnevel. Voor de 1ste keer worden Thermaal Bronwater van Vichy, rijk aan zeldzame mineralen en Actief HyaluronineтДв verwerkt in microcapsules, die deze vervolgens verspreiden in de cellen.

04.TEXTUUR
De lichte cr├иme is verfrissend en trekt makkelijk in. Niet vet en niet kleverig. Zonder 'maskereffect'.

05.GEUR
Geparfumeerd

06.INHOUD
40 ml tube
EOS parser = LibXML::XML::SaxParser.string(xml) parser.callbacks = TestCaseCallbacks.new error = assert_raises(LibXML::XML::Error) do parser.parse end assert_equal("Fatal error: xmlParseEntityRef: no name at :5.", error.to_s) # Check callbacks parser.callbacks.result end end libxml-ruby-3.2.1/test/test_xpath_context.rb0000644000004100000410000000522613760147770021267 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' require "tempfile" class TestXPathContext < Minitest::Test SOAP_PREFIX = 'soap' SOAP_URI = 'http://schemas.xmlsoap.org/soap/envelope/' NS0_PREFIX = 'ns0' NS0_URI = 'http://services.somewhere.com' def setup doc = LibXML::XML::Document.file(File.join(File.dirname(__FILE__), 'model/soap.xml')) @context = LibXML::XML::XPath::Context.new(doc) end def teardown() @context = nil end def test_no_ns error = assert_raises(LibXML::XML::Error) do @context.find('/soap:Envelope') end assert_equal("Error: Undefined namespace prefix.", error.to_s) end def test_ns_register @context.register_namespace(SOAP_PREFIX, SOAP_URI) @context.register_namespace(NS0_PREFIX, NS0_URI) nodes = @context.find('/soap:Envelope/soap:Body/ns0:getManufacturerNamesResponse') assert_equal(1, nodes.length) end def test_ns_register_string @context.register_namespaces("#{SOAP_PREFIX}:#{SOAP_URI}") @context.register_namespaces("#{NS0_PREFIX}:#{NS0_URI}") nodes = @context.find('/soap:Envelope/soap:Body/ns0:getManufacturerNamesResponse') assert_equal(1, nodes.length) end def test_ns_register_array @context.register_namespaces(["#{SOAP_PREFIX}:#{SOAP_URI}", "#{NS0_PREFIX}:#{NS0_URI}"]) nodes = @context.find('/soap:Envelope/soap:Body/ns0:getManufacturerNamesResponse') assert_equal(1, nodes.length) end def test_ns_register_hash @context.register_namespaces(SOAP_PREFIX => SOAP_URI, NS0_PREFIX => NS0_URI) nodes = @context.find('/soap:Envelope/soap:Body/ns0:getManufacturerNamesResponse') assert_equal(1, nodes.length) end def test_ns_register_node @context.register_namespaces_from_node(@context.doc.root) nodes = @context.find('/soap:Envelope') assert_equal(1, nodes.length) end def test_node @context.register_namespaces_from_node(@context.doc.root) nodes = @context.find('soap:Body') assert_equal(0, nodes.length) @context.node = @context.doc.root.child.next nodes = @context.find('soap:Body') assert_equal(0, nodes.length) end def test_cache @context.enable_cache @context.enable_cache(10) @context.disable_cache end def test_require_doc doc = LibXML::XML::Document.file(File.join(File.dirname(__FILE__), 'model/soap.xml')) error = assert_raises(TypeError) do @context = LibXML::XML::XPath::Context.new(doc.root) end assert_equal("Supplied argument must be a document or node.", error.to_s) end endlibxml-ruby-3.2.1/test/test_writer.rb0000644000004100000410000003715713760147770017723 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' require 'stringio' class TestWriter < Minitest::Test XSL_PREFIX = 'xsl' XSL_URI = 'http://www.w3.org/1999/XSL/Transform' def test_generic_failure writer = LibXML::XML::Writer.string writer.start_document assert(!writer.end_element) writer.end_document end def test_empty_doc writer = LibXML::XML::Writer.string document(writer) assert_equal(writer.result.strip!, '') writer = LibXML::XML::Writer.string document(writer, :encoding => LibXML::XML::Encoding::ISO_8859_1) assert_equal(writer.result.strip!, '') writer = LibXML::XML::Writer.string document(writer, :standalone => 1) assert_equal(writer.result.strip!, '') writer = LibXML::XML::Writer.string document(writer, :standalone => 1, :encoding => LibXML::XML::Encoding::ISO_8859_1, :foo => :bar) assert_equal(writer.result.strip!, '') end def test_file_encoding value = "François".encode(Encoding::UTF_8) File.open('test.xml', 'wb', encoding: 'UTF-8') do |file| writer = LibXML::XML::Writer::io(file) document(writer, encoding: LibXML::XML::Encoding::UTF_8) do writer.write_element('Name', value) end end end def test_io_encoding value = "François".encode(Encoding::UTF_8) expected = "\nFrançois".encode(Encoding::UTF_8) io = StringIO.new writer = LibXML::XML::Writer::io(io) document(writer, encoding: LibXML::XML::Encoding::UTF_8) do writer.write_element('Name', value) end assert_equal(expected, io.string.strip) end def test_single_root writer = LibXML::XML::Writer.string document(writer) do element writer, 'root' end assert_equal(writer.result.strip!, "\n") end def test_pi expected = "\n" writer = LibXML::XML::Writer.string document(writer) do assert(writer.start_pi('php')) assert(writer.write_string('echo "foo";')) assert(writer.end_pi) end assert_equal(writer.result.strip!, expected) writer = LibXML::XML::Writer.string document(writer) do assert(writer.write_pi('php', 'echo "foo";')) end assert_equal(writer.result.strip!, expected) end def test_comment expected = "\n" writer = LibXML::XML::Writer.string document(writer) do assert(writer.start_comment) assert(writer.write_string 'foo') assert(writer.end_comment) end assert_equal(writer.result.strip!, expected) writer = LibXML::XML::Writer.string document(writer) do assert(writer.write_comment 'foo') end assert_equal(writer.result.strip!, expected) end def test_cdata expected = "\n]]>" writer = LibXML::XML::Writer.string document(writer) do element writer, 'root' do assert(writer.start_cdata) assert(writer.write_string '') assert(writer.end_cdata) end end assert_equal(writer.result.strip!, expected) writer = LibXML::XML::Writer.string document(writer) do element writer, 'root' do assert(writer.write_cdata '') end end assert_equal(writer.result.strip!, expected) end def test_write_empty_elements writer = LibXML::XML::Writer.string document(writer) do assert(writer.write_element 'foo') end assert_equal(writer.result.strip!, "\n") writer = LibXML::XML::Writer.string document(writer) do assert(writer.write_element_ns XSL_PREFIX, 'stylesheet', XSL_URI) end assert_equal(writer.result.strip!, "\n<" + XSL_PREFIX + ":stylesheet xmlns:xsl=\"" + XSL_URI + "\"/>") end def test_valued_element expected = "\n123456789cueillir des cerisesnous irons au bois" writer = LibXML::XML::Writer.string document(writer) do assert(writer.start_element 'abc') assert(writer.write_string '123') assert(writer.start_element 'def') assert(writer.write_string '456') assert(writer.start_element 'ghi') assert(writer.write_string '789') assert(writer.end_element) assert(writer.write_string 'cueillir des cerises') assert(writer.end_element) assert(writer.write_string 'nous irons au bois') assert(writer.end_element) end assert_equal(writer.result.strip!, expected) writer = LibXML::XML::Writer.string document(writer) do assert(writer.start_element 'abc') assert(writer.write_string '123') assert(writer.start_element 'def') assert(writer.write_string '456') assert(writer.write_element 'ghi', '789') assert(writer.write_string 'cueillir des cerises') assert(writer.end_element) assert(writer.write_string 'nous irons au bois') assert(writer.end_element) end assert_equal(writer.result.strip!, expected) end def test_valued_element_ns expected = "\n" + "" + "" + "20px" + "solid" + "" + "" writer = LibXML::XML::Writer.string document(writer) do assert(writer.start_element_ns XSL_PREFIX, 'stylesheet', XSL_URI) assert(writer.start_element_ns XSL_PREFIX, 'attribute-set') assert(writer.start_element_ns XSL_PREFIX, 'attribute') assert(writer.write_string '20px') assert(writer.end_element) assert(writer.start_element_ns XSL_PREFIX, 'attribute') assert(writer.write_string 'solid') assert(writer.end_element) assert(writer.end_element) assert(writer.end_element) end assert_equal(writer.result.strip!, expected) writer = LibXML::XML::Writer.string document(writer) do assert(writer.start_element_ns XSL_PREFIX, 'stylesheet', XSL_URI) assert(writer.start_element_ns XSL_PREFIX, 'attribute-set') assert(writer.write_element_ns XSL_PREFIX, 'attribute', nil, '20px') assert(writer.write_element_ns XSL_PREFIX, 'attribute', nil, 'solid') assert(writer.end_element) assert(writer.end_element) end assert_equal(writer.result.strip!, expected) end def test_attribute writer = LibXML::XML::Writer.string document(writer) do element writer, 'root' do element writer, 'child' do assert(writer.start_attribute 'foo') assert(writer.write_string 'bar') assert(writer.end_attribute) end end end assert_equal(writer.result.strip!, "\n") writer = LibXML::XML::Writer.string document(writer) do element writer, 'root' do element writer, 'child' do assert(writer.write_attribute 'abc', 'def') assert(writer.write_string 'ghi') # must be done after attributes end end end assert_equal(writer.result.strip!, "\nghi") end def test_attribute_ns expected = "\n" writer = LibXML::XML::Writer.string document(writer) do element writer, 'root' do element writer, 'link' do assert(writer.write_attribute_ns 'xlink', 'href', nil, 'abc') assert(writer.write_attribute_ns 'xhtml', 'class', nil, 'def') end end end assert_equal(writer.result.strip!, expected) writer = LibXML::XML::Writer.string document(writer) do element writer, 'root' do element writer, 'link' do assert(writer.start_attribute_ns 'xlink', 'href') assert(writer.write_string 'abc') assert(writer.end_attribute) assert(writer.start_attribute_ns 'xhtml', 'class') assert(writer.write_string 'def') assert(writer.end_attribute) end end end assert_equal(writer.result.strip!, expected) end def test_quote_char if LibXML::XML::Writer.method_defined? :set_quote_char writer = LibXML::XML::Writer.string writer.set_quote_char "'" document(writer) do element writer, 'root' do assert(writer.start_attribute 'abc') assert(writer.write_string 'def') assert(writer.end_attribute) end end assert(writer.result.strip!.end_with? "") end end def test_indentation_on if LibXML::XML::Writer.method_defined? :set_indent writer = LibXML::XML::Writer.string assert(writer.set_indent true) document(writer) do element writer, 'root' do element writer, 'child' do assert(writer.start_attribute 'abc') assert(writer.write_string 'def') assert(writer.end_attribute) end end end assert_equal(writer.result.strip!, "\n\n \n") end end def test_indentation_string if LibXML::XML::Writer.method_defined? :set_indent_string writer = LibXML::XML::Writer.string assert(writer.set_indent true) assert(writer.set_indent_string ' ' * 4) document(writer) do element writer, 'root' do element writer, 'child' do assert(writer.start_attribute 'abc') assert(writer.write_string 'def') assert(writer.end_attribute) end end end assert_equal(writer.result.strip!, "\n\n \n") end end def test_dtd_declaration writer = LibXML::XML::Writer.string dtd writer, 'html' assert_equal(writer.result, '') writer = LibXML::XML::Writer.string dtd writer, 'html', '-//W3C//DTD XHTML 1.0 Strict//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd' assert_equal(writer.result, '') end def test_dtd_attlist expected = ']>' writer = LibXML::XML::Writer.string dtd writer, 'http' do assert(writer.start_dtd_attlist 'method') assert(writer.write_string '(get|post) "get"') assert(writer.end_dtd_attlist) end assert_equal(writer.result, expected) writer = LibXML::XML::Writer.string dtd writer, 'http' do assert(writer.write_dtd_attlist 'method', '(get|post) "get"') end assert_equal(writer.result, expected) end def test_dtd_element expected = ']>' writer = LibXML::XML::Writer.string dtd writer, 'html' do assert(writer.start_dtd_element 'dl') assert(writer.write_string '(dt|dd)+') assert(writer.end_dtd_element) end assert_equal(writer.result, expected) writer = LibXML::XML::Writer.string dtd writer, 'html' do assert(writer.write_dtd_element 'dl', '(dt|dd)+') end assert_equal(writer.result, expected) end def test_dtd_entity # parameterized entity expected = ']>' writer = LibXML::XML::Writer.string dtd writer, 'html' do assert(writer.start_dtd_entity 'special.pre', true) assert(writer.write_string 'br | span | bdo | map') assert(writer.end_dtd_entity) assert(writer.start_dtd_entity 'special', true) assert(writer.write_string '%special.pre; | object | img') assert(writer.end_dtd_entity) end assert_equal(writer.result, expected) writer = LibXML::XML::Writer.string dtd writer, 'html' do assert(writer.write_dtd_internal_entity 'special.pre', 'br | span | bdo | map', true) assert(writer.write_dtd_internal_entity 'special', '%special.pre; | object | img', true) end assert_equal(writer.result, expected) # non parameterized entity expected = ']>' writer = LibXML::XML::Writer.string dtd writer, 'html' do assert(writer.start_dtd_entity 'Alpha') assert(writer.write_string 'Α') assert(writer.end_dtd_entity) end assert_equal(writer.result, expected) writer = LibXML::XML::Writer.string dtd writer, 'html' do assert(writer.start_dtd_entity 'Alpha', false) assert(writer.write_string 'Α') assert(writer.end_dtd_entity) end assert_equal(writer.result, expected) writer = LibXML::XML::Writer.string dtd writer, 'html' do assert(writer.write_dtd_internal_entity 'Alpha', 'Α', false) end assert_equal(writer.result, expected) end def test_dtd_notation writer = LibXML::XML::Writer.string dtd writer, 'pictures' do assert(writer.write_dtd_notation 'GIF89a', '-//Compuserve//NOTATION Graphics Interchange Format 89a//EN', nil) assert(writer.write_dtd_external_entity 'pictures', nil, 'images/plage.gif', 'GIF89a', false) end assert_equal(writer.result, ']>') end def test_encoding iso = 'éloïse'.encode 'ISO-8859-1' writer = LibXML::XML::Writer.string document(writer) do assert(writer.write_element iso) end assert_equal(writer.result.strip!, "\n<éloïse/>") end def test_flush writer = LibXML::XML::Writer.string assert(writer.start_document) assert_equal(writer.flush.strip!, '') assert(writer.start_element 'foo') assert(writer.end_element) assert(writer.end_document) writer.flush false assert_equal(writer.result.strip, '') end def test_nil_pe_issue expected = ']>' writer = LibXML::XML::Writer.string dtd writer, 'html' do assert(writer.write_dtd_internal_entity 'special.pre', 'br | span | bdo | map', nil) assert(writer.write_dtd_internal_entity 'special', '%special.pre; | object | img', nil) end assert_equal(writer.result, expected) end private def document(writer, options = {}) assert(writer.start_document options) yield if block_given? assert(writer.end_document) end def dtd(writer, name, pubid = nil, sysid = nil) assert(writer.start_dtd name, pubid, sysid) yield if block_given? assert(writer.end_dtd) end def element(writer, localname) assert(writer.start_element localname) yield if block_given? assert(writer.end_element) end end libxml-ruby-3.2.1/test/c14n/0000755000004100000410000000000013760147770015553 5ustar www-datawww-datalibxml-ruby-3.2.1/test/c14n/result/0000755000004100000410000000000013760147770017071 5ustar www-datawww-datalibxml-ruby-3.2.1/test/c14n/result/without-comments/0000755000004100000410000000000013760147770022417 5ustar www-datawww-datalibxml-ruby-3.2.1/test/c14n/result/without-comments/example-40000644000004100000410000000060113760147770024133 0ustar www-datawww-data First line Second line 2 value>"0" && value<"10" ?"valid":"error" valid libxml-ruby-3.2.1/test/c14n/result/without-comments/example-70000644000004100000410000000016213760147770024140 0ustar www-datawww-datalibxml-ruby-3.2.1/test/c14n/result/without-comments/example-10000644000004100000410000000014713760147770024135 0ustar www-datawww-data Hello, world! libxml-ruby-3.2.1/test/c14n/result/without-comments/example-50000644000004100000410000000006313760147770024136 0ustar www-datawww-data Hello, world! libxml-ruby-3.2.1/test/c14n/result/without-comments/example-60000644000004100000410000000001513760147770024134 0ustar www-datawww-data©libxml-ruby-3.2.1/test/c14n/result/without-comments/example-30000644000004100000410000000074513760147770024143 0ustar www-datawww-data libxml-ruby-3.2.1/test/c14n/result/without-comments/example-20000644000004100000410000000026313760147770024135 0ustar www-datawww-data A B A B A B C libxml-ruby-3.2.1/test/c14n/result/1-1-without-comments/0000755000004100000410000000000013760147770022713 5ustar www-datawww-datalibxml-ruby-3.2.1/test/c14n/result/1-1-without-comments/example-40000644000004100000410000000060113760147770024427 0ustar www-datawww-data First line Second line 2 value>"0" && value<"10" ?"valid":"error" valid libxml-ruby-3.2.1/test/c14n/result/1-1-without-comments/example-70000644000004100000410000000016213760147770024434 0ustar www-datawww-datalibxml-ruby-3.2.1/test/c14n/result/1-1-without-comments/example-10000644000004100000410000000014713760147770024431 0ustar www-datawww-data Hello, world! libxml-ruby-3.2.1/test/c14n/result/1-1-without-comments/example-80000644000004100000410000000023713760147770024440 0ustar www-datawww-datalibxml-ruby-3.2.1/test/c14n/result/1-1-without-comments/example-50000644000004100000410000000006313760147770024432 0ustar www-datawww-data Hello, world! libxml-ruby-3.2.1/test/c14n/result/1-1-without-comments/example-60000644000004100000410000000001513760147770024430 0ustar www-datawww-data©libxml-ruby-3.2.1/test/c14n/result/1-1-without-comments/example-30000644000004100000410000000074513760147770024437 0ustar www-datawww-data libxml-ruby-3.2.1/test/c14n/result/1-1-without-comments/example-20000644000004100000410000000026313760147770024431 0ustar www-datawww-data A B A B A B C libxml-ruby-3.2.1/test/c14n/result/with-comments/0000755000004100000410000000000013760147770021667 5ustar www-datawww-datalibxml-ruby-3.2.1/test/c14n/result/with-comments/example-40000644000004100000410000000060113760147770023403 0ustar www-datawww-data First line Second line 2 value>"0" && value<"10" ?"valid":"error" valid libxml-ruby-3.2.1/test/c14n/result/with-comments/example-70000644000004100000410000000016213760147770023410 0ustar www-datawww-datalibxml-ruby-3.2.1/test/c14n/result/with-comments/example-10000644000004100000410000000024113760147770023400 0ustar www-datawww-data Hello, world! libxml-ruby-3.2.1/test/c14n/result/with-comments/example-50000644000004100000410000000016213760147770023406 0ustar www-datawww-data Hello, world! libxml-ruby-3.2.1/test/c14n/result/with-comments/example-60000644000004100000410000000001513760147770023404 0ustar www-datawww-data©libxml-ruby-3.2.1/test/c14n/result/with-comments/example-30000644000004100000410000000074513760147770023413 0ustar www-datawww-data libxml-ruby-3.2.1/test/c14n/result/with-comments/example-20000644000004100000410000000026313760147770023405 0ustar www-datawww-data A B A B A B C libxml-ruby-3.2.1/test/c14n/given/0000755000004100000410000000000013760147770016663 5ustar www-datawww-datalibxml-ruby-3.2.1/test/c14n/given/example-2.xml0000644000004100000410000000026513760147770021202 0ustar www-datawww-data A B A B A B C libxml-ruby-3.2.1/test/c14n/given/example-7.xml0000644000004100000410000000040013760147770021176 0ustar www-datawww-data ]> libxml-ruby-3.2.1/test/c14n/given/example-6.xml0000644000004100000410000000010013760147770021172 0ustar www-datawww-data © libxml-ruby-3.2.1/test/c14n/given/example-5.xml0000644000004100000410000000051013760147770021176 0ustar www-datawww-data ]> &ent1;, &ent2;! libxml-ruby-3.2.1/test/c14n/given/example-3.xml0000644000004100000410000000115513760147770021202 0ustar www-datawww-data]> libxml-ruby-3.2.1/test/c14n/given/example-1.xml0000644000004100000410000000035613760147770021202 0ustar www-datawww-data Hello, world! libxml-ruby-3.2.1/test/c14n/given/example-4.xml0000644000004100000410000000065213760147770021204 0ustar www-datawww-data]> First line Second line 2 "0" && value<"10" ?"valid":"error"]]> valid libxml-ruby-3.2.1/test/c14n/given/doc.dtd0000644000004100000410000000002213760147770020117 0ustar www-datawww-datalibxml-ruby-3.2.1/test/c14n/given/example-8.xpath0000644000004100000410000000040513760147770021530 0ustar www-datawww-data (//.|//@*|//namespace::*) [ self::ietf:e1 or (parent::ietf:e1 and not(self::text() or self::e2)) or count(id("E3")|ancestor-or-self::node()) = count(ancestor-or-self::node()) ] libxml-ruby-3.2.1/test/c14n/given/example-8.xml0000644000004100000410000000050613760147770021206 0ustar www-datawww-data ]> libxml-ruby-3.2.1/test/c14n/given/world.txt0000644000004100000410000000000513760147770020546 0ustar www-datawww-dataworldlibxml-ruby-3.2.1/test/test_xml.rb0000644000004100000410000001565013760147770017201 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' require 'stringio' class TestXml < Minitest::Test # ----- Constants ------ def test_lib_versions assert(LibXML::XML.check_lib_versions) end def test_debug_entities original = LibXML::XML.debug_entities LibXML::XML.debug_entities = false refute(LibXML::XML.debug_entities) LibXML::XML.debug_entities = true assert(LibXML::XML.debug_entities) LibXML::XML.debug_entities = false refute(LibXML::XML.debug_entities) LibXML::XML.debug_entities = original end def test_default_compression return unless LibXML::XML.default_compression original = LibXML::XML.default_compression 0.upto(9) do |i| LibXML::XML.default_compression = i assert_equal(i, LibXML::XML.default_compression) end 9.downto(0) do |i| assert_equal(i, LibXML::XML.default_compression = i) assert_equal(i, LibXML::XML.default_compression) end 0.downto(-10) do |i| assert_equal(i, LibXML::XML.default_compression = i) assert_equal(0, LibXML::XML.default_compression) end 10.upto(20) do |i| assert_equal(i, LibXML::XML.default_compression = i) assert_equal(9, LibXML::XML.default_compression) end LibXML::XML.default_compression = original end def test_default_keep_blanks original = LibXML::XML.default_keep_blanks LibXML::XML.default_keep_blanks = false refute(LibXML::XML.default_keep_blanks) assert_equal(LibXML::XML::Parser::Options::NOBLANKS, LibXML::XML.default_options) LibXML::XML.default_keep_blanks = true assert(LibXML::XML.default_keep_blanks) assert_equal(0, LibXML::XML.default_options) LibXML::XML.default_keep_blanks = original end def test_default_line_numbers original = LibXML::XML.default_line_numbers LibXML::XML.default_line_numbers = false refute(LibXML::XML.default_line_numbers) LibXML::XML.default_line_numbers = true assert(LibXML::XML.default_line_numbers) LibXML::XML.default_line_numbers = false refute(LibXML::XML.default_line_numbers) LibXML::XML.default_line_numbers = original end def test_default_substitute_entities original = LibXML::XML.default_substitute_entities LibXML::XML.default_substitute_entities = false refute(LibXML::XML.default_substitute_entities) assert_equal(0, LibXML::XML.default_options) LibXML::XML.default_substitute_entities = true assert(LibXML::XML.default_substitute_entities) assert_equal(LibXML::XML::Parser::Options::NOENT, LibXML::XML.default_options) LibXML::XML.default_substitute_entities = false refute(LibXML::XML.default_substitute_entities) LibXML::XML.default_substitute_entities = original end def test_default_tree_indent_string original = LibXML::XML.default_tree_indent_string s = LibXML::XML.default_tree_indent_string assert_instance_of(String, s) assert_equal(' ', s) LibXML::XML.default_tree_indent_string = 'uga' s = LibXML::XML.default_tree_indent_string assert_instance_of(String, s) assert_equal('uga', s) LibXML::XML.default_tree_indent_string = ' ' s = LibXML::XML.default_tree_indent_string assert_instance_of(String, s) assert_equal(' ', s) LibXML::XML.default_tree_indent_string = original end def test_default_validity_checking original = LibXML::XML.default_validity_checking LibXML::XML.default_validity_checking = false refute(LibXML::XML.default_validity_checking) assert_equal(0, LibXML::XML.default_options) LibXML::XML.default_validity_checking = true assert(LibXML::XML.default_validity_checking) assert_equal(LibXML::XML::Parser::Options::DTDVALID, LibXML::XML.default_options) LibXML::XML.default_validity_checking = false refute(LibXML::XML.default_validity_checking) LibXML::XML.default_validity_checking = original end def test_default_warnings original = LibXML::XML.default_warnings LibXML::XML.default_warnings = false refute(LibXML::XML.default_warnings) assert_equal(LibXML::XML::Parser::Options::NOWARNING, LibXML::XML.default_options) LibXML::XML.default_warnings = true assert(LibXML::XML.default_warnings) assert_equal(0, LibXML::XML.default_options) LibXML::XML.default_warnings = false refute(LibXML::XML.default_warnings) LibXML::XML.default_warnings = original end def test_enabled_automata assert(LibXML::XML.enabled_automata?) end def test_enabled_c14n assert(LibXML::XML.enabled_c14n?) end def test_enabled_catalog assert(LibXML::XML.enabled_catalog?) end def test_enabled_debug assert(LibXML::XML.enabled_debug?) end def test_enabled_docbook assert(LibXML::XML.enabled_docbook?) end def test_enabled_ftp assert(LibXML::XML.enabled_ftp?) end def test_enabled_http assert(LibXML::XML.enabled_http?) end def test_enabled_html assert(LibXML::XML.enabled_html?) end def test_enabled_iconv assert(LibXML::XML.enabled_iconv?) end def test_enabled_memory_debug assert_equal(false, LibXML::XML.enabled_memory_debug?) end def test_enabled_regexp assert(LibXML::XML.enabled_regexp?) end def test_enabled_schemas assert(LibXML::XML.enabled_schemas?) end def test_enabled_thread assert(LibXML::XML.enabled_thread?) end def test_enabled_unicode assert(LibXML::XML.enabled_unicode?) end def test_enabled_xinclude assert(LibXML::XML.enabled_xinclude?) end def test_enabled_xpath assert(LibXML::XML.enabled_xpath?) end def test_enabled_xpointer assert(LibXML::XML.enabled_xpointer?) end def test_enabled_zlib assert(LibXML::XML.enabled_zlib?.is_a?(TrueClass) || LibXML::XML.enabled_zlib?.is_a?(FalseClass)) end def test_intent_tree_output assert(TrueClass, LibXML::XML.indent_tree_output) LibXML::XML.indent_tree_output = false assert(FalseClass, LibXML::XML.indent_tree_output) LibXML::XML.indent_tree_output = true assert(TrueClass, LibXML::XML.indent_tree_output) end def test_version assert_instance_of(String, LibXML::XML::VERSION) end def test_vernum assert_instance_of(Integer, LibXML::XML::VERNUM) end def test_libxml_parser_features assert_instance_of(Array, LibXML::XML.features) end def test_default_options assert_equal(0, LibXML::XML.default_options) end def test_default_save_no_empty_tags original = LibXML::XML.default_save_no_empty_tags LibXML::XML.default_save_no_empty_tags = false refute(LibXML::XML.default_save_no_empty_tags) LibXML::XML.default_save_no_empty_tags = true assert(LibXML::XML.default_save_no_empty_tags) LibXML::XML.default_save_no_empty_tags = original end end libxml-ruby-3.2.1/test/test_properties.rb0000644000004100000410000000177413760147770020577 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' # attributes is deprecated - use attributes instead. # Tests for backwards compatibility class Testattributes < Minitest::Test def setup() xp = LibXML::XML::Parser.string('onetwo') @doc = xp.parse end def teardown() @doc = nil end def test_traversal attributes = @doc.root.attributes assert_instance_of(LibXML::XML::Attributes, attributes) attribute = attributes.first assert_equal('uga', attribute.name) assert_equal('booga', attribute.value) attribute = attribute.next assert_instance_of(LibXML::XML::Attr, attribute) assert_equal('foo', attribute.name) assert_equal('bar', attribute.value) end def test_no_attributes attributes = @doc.root.child.attributes assert_instance_of(LibXML::XML::Attributes, attributes) assert_equal(0, attributes.length) end end libxml-ruby-3.2.1/test/test_reader.rb0000644000004100000410000003220313760147770017634 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' require 'stringio' class TestReader < Minitest::Test XML_FILE = File.join(File.dirname(__FILE__), 'model/atom.xml') def verify_simple(reader) node_types = [] # Read each node 26.times do assert(reader.read) node_types << reader.node_type end # There are no more nodes assert(!reader.read) # Check what was read expected = [LibXML::XML::Reader::TYPE_PROCESSING_INSTRUCTION, LibXML::XML::Reader::TYPE_ELEMENT, LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, LibXML::XML::Reader::TYPE_COMMENT, LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, LibXML::XML::Reader::TYPE_ELEMENT, LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, LibXML::XML::Reader::TYPE_ELEMENT, LibXML::XML::Reader::TYPE_CDATA, LibXML::XML::Reader::TYPE_END_ELEMENT, LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, LibXML::XML::Reader::TYPE_ELEMENT, LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, LibXML::XML::Reader::TYPE_ELEMENT, LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, LibXML::XML::Reader::TYPE_ELEMENT, LibXML::XML::Reader::TYPE_TEXT, LibXML::XML::Reader::TYPE_END_ELEMENT, LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, LibXML::XML::Reader::TYPE_END_ELEMENT, LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, LibXML::XML::Reader::TYPE_END_ELEMENT, LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, LibXML::XML::Reader::TYPE_END_ELEMENT, LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, LibXML::XML::Reader::TYPE_END_ELEMENT] assert_equal(expected, node_types) end def test_document reader = LibXML::XML::Reader.document(LibXML::XML::Document.file(XML_FILE)) verify_simple(reader) end def test_file reader = LibXML::XML::Reader.file(XML_FILE) verify_simple(reader) end def test_invalid_file assert_raises(LibXML::XML::Error) do LibXML::XML::Reader.file('/does/not/exist') end end def test_string reader = LibXML::XML::Reader.string(File.read(XML_FILE)) verify_simple(reader) end def test_io File.open(XML_FILE, 'rb') do |io| reader = LibXML::XML::Reader.io(io) verify_simple(reader) end end def test_io_gc # Test that the reader keeps a reference # to the io object file = File.open(XML_FILE, 'rb') reader = LibXML::XML::Reader.io(file) file = nil GC.start assert(reader.read) end def test_string_io data = File.read(XML_FILE) string_io = StringIO.new(data) reader = LibXML::XML::Reader.io(string_io) verify_simple(reader) end def test_error reader = LibXML::XML::Reader.string('") assert(parser.read) assert_equal('foo', parser.name) assert_equal('1', parser['x']) assert_equal('1', parser[0]) assert_equal('2', parser['y']) assert_equal('2', parser[1]) assert_nil(parser['z']) assert_nil(parser[2]) end def test_move_attr reader = LibXML::XML::Reader.string('') assert(reader.read) # assert(reader.read) # assert(reader.move_to_attribute_no(1)) assert_equal(reader.value, 'def') assert(reader.move_to_attribute_ns('id', 'http://www.w3.org/XML/1998/namespace')) assert_equal(reader.value, 'abc') assert(reader.move_to_attribute('bar')) assert_equal(reader.value, 'jkl') # 1 in case of success, -1 in case of error, 0 if not found assert_equal(reader.move_to_attribute_no(12), 0) assert_equal(reader.move_to_attribute('baz'), 0) assert_equal(reader.move_to_attribute_ns('baz', 'http://ruby/namespace'), 0) end def test_get_attr reader = LibXML::XML::Reader.string('') assert(reader.read) # assert(reader.read) # assert_equal(reader.get_attribute_no(1), 'def') assert_equal(reader.get_attribute_ns('id', 'http://www.w3.org/XML/1998/namespace'), 'abc') assert_equal(reader.get_attribute('bar'), 'jkl') assert_nil(reader.get_attribute_no(12)) assert_nil(reader.get_attribute('baz')) assert_nil(reader.get_attribute_ns('baz', 'http://ruby/namespace')) end def test_value parser = LibXML::XML::Reader.string("123") assert(parser.read) assert_equal('foo', parser.name) assert_nil(parser.value) 3.times do |i| assert(parser.read) assert_equal(LibXML::XML::Reader::TYPE_ELEMENT, parser.node_type) assert_equal('bar', parser.name) assert(parser.read) assert_equal(LibXML::XML::Reader::TYPE_TEXT, parser.node_type) assert_equal((i + 1).to_s, parser.value) assert(parser.read) assert_equal(LibXML::XML::Reader::TYPE_END_ELEMENT, parser.node_type) end end def test_expand reader = LibXML::XML::Reader.file(XML_FILE) reader.read.to_s reader.read # Read a node node = reader.expand refute_nil(node.doc) assert_equal('feed', node.name) assert_equal(::Encoding::UTF_8, node.name.encoding) if defined?(::Encoding) end def test_expand_find reader = LibXML::XML::Reader.file(XML_FILE) reader.read.to_s reader.read # Read first node which node = reader.expand assert_equal('feed', node.name) # We need to create document to use xpath reader.doc # Search for entries entries = node.find('atom:entry', 'atom:http://www.w3.org/2005/Atom') assert_equal(1, entries.length) end def test_expand_invalid reader = LibXML::XML::Reader.file(XML_FILE) # Expand a node before one has been read node = reader.expand assert_nil(node) end def test_expand_should_be_invalid reader = LibXML::XML::Reader.file(XML_FILE) # Read a couple of nodes reader.read reader.read # Expand the node node = reader.expand assert_equal('feed', node.name) # Read another node, this makes the last node invalid reader.next # The previous node is now invalid - this should be an error but isn't assert_equal('feed', node.name) end def test_expand_incorrectly_use_returned_node file = File.join(File.dirname(__FILE__), 'model/cwm_1_0.xml') reader = LibXML::XML::Reader.file(file) nodes = Array.new while reader.read node = reader.expand refute_nil(node) refute_nil(node.doc) # NOTE - DO NOT do this in real code, these nodes are invalid after the next read. This *will* cause # a segmentation fault next time the garbage collector runs. The reason is the parent node will be # called in the mark phase, but its underlying xml node will be gone. Same goes for calling children, # attributes, etc. You must let go of the expanded node *before* calling xml reader again and # call the garbage collector to be safe. #refute_nil(node.parent) nodes << node end assert(true) end def test_mode reader = LibXML::XML::Reader.string('') assert_equal(LibXML::XML::Reader::MODE_INITIAL, reader.read_state) reader.read assert_equal(LibXML::XML::Reader::MODE_EOF, reader.read_state) end def test_bytes_consumed reader = LibXML::XML::Reader.file(XML_FILE) reader.read assert_equal(428, reader.byte_consumed) end def test_node LibXML::XML.default_line_numbers = true reader = LibXML::XML::Reader.file(XML_FILE) # first try to get a node assert_nil(reader.node) reader.read assert_instance_of(LibXML::XML::Node, reader.node) end def test_base_uri # UTF8: # ö - c3 b6 in hex, \303\266 in octal # ü - c3 bc in hex, \303\274 in octal xml = "\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n" reader = LibXML::XML::Reader.string(xml, :base_uri => "http://libxml.rubyforge.org") reader.read assert_equal(reader.base_uri, "http://libxml.rubyforge.org") assert_equal(::Encoding::UTF_8, reader.base_uri.encoding) if defined?(::Encoding) end def test_options xml = <<-EOS ]> &foo; EOS # Parse normally reader = LibXML::XML::Reader.string(xml) reader.read # foo reader.read # test reader.read # text reader.read # cdata reader.read # cdata-section assert_equal(LibXML::XML::Node::CDATA_SECTION_NODE, reader.node_type) # Convert cdata section to text reader = LibXML::XML::Reader.string(xml, :options => LibXML::XML::Parser::Options::NOCDATA) reader.read # foo reader.read # test reader.read # text reader.read # cdata reader.read # cdata-section assert_equal(LibXML::XML::Node::TEXT_NODE, reader.node_type) end def test_encoding # ISO_8859_1: # ö - f6 in hex, \366 in octal # ü - fc in hex, \374 in octal xml = "\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n" reader = LibXML::XML::Reader.string(xml, :encoding => LibXML::XML::Encoding::ISO_8859_1) reader.read assert_equal(Encoding::ISO8859_1, reader.read_outer_xml.encoding) assert_equal(Encoding::ISO8859_1, reader.read_inner_xml.encoding) assert_equal(Encoding::ISO8859_1, reader.read_string.encoding) assert_equal("\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n".force_encoding(Encoding::ISO8859_1), reader.read_outer_xml) assert_equal("\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n".force_encoding(Encoding::ISO8859_1), reader.read_inner_xml) assert_equal("\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n".force_encoding(Encoding::ISO8859_1), reader.read_string) end def test_invalid_encoding # ISO_8859_1: # ö - f6 in hex, \366 in octal # ü - fc in hex, \374 in octal xml = "\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n" reader = LibXML::XML::Reader.string(xml) error = assert_raises(LibXML::XML::Error) do reader.read end assert_equal("Fatal error: Input is not proper UTF-8, indicate encoding !\nBytes: 0xF6 0x74 0x6C 0x65 at :2.", error.to_s) end def test_file_encoding reader = LibXML::XML::Reader.file(XML_FILE) reader.read assert_equal(LibXML::XML::Encoding::UTF_8, reader.encoding) assert_equal(Encoding::UTF_8, reader.value.encoding) end def test_string_encoding # ISO_8859_1: # ö - f6 in hex, \366 in octal # ü - fc in hex, \374 in octal xml = "\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n" reader = LibXML::XML::Reader.string(xml, :encoding => LibXML::XML::Encoding::ISO_8859_1) reader.read # Encoding is always null for strings, very annoying! assert_equal(reader.encoding, LibXML::XML::Encoding::NONE) end end libxml-ruby-3.2.1/test/test_attributes.rb0000644000004100000410000000773613760147770020575 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class AttributesTest < Minitest::Test def setup xp = LibXML::XML::Parser.string(<<-EOS) EOS @doc = xp.parse end def teardown @doc = nil end def city_member @doc.find('/city:CityModel/city:cityMember').first end def test_attributes attributes = city_member.attributes assert_instance_of(LibXML::XML::Attributes, attributes) assert_equal(5, attributes.length) end def test_each attributes = city_member.attributes length = attributes.inject(0) do |result, attr| assert_instance_of(LibXML::XML::Attr, attr) result + 1 end assert_equal(5, length) end def test_get_attribute attributes = city_member.attributes attr = attributes.get_attribute('name') assert_instance_of(LibXML::XML::Attr, attr) attr = attributes.get_attribute('does_not_exist') assert_nil(attr) attr = attributes.get_attribute('name') assert_instance_of(LibXML::XML::Attr, attr) attr = attributes.get_attribute('href') assert_instance_of(LibXML::XML::Attr, attr) assert_instance_of(LibXML::XML::Namespace, attr.ns) assert_equal('xlink', attr.ns.prefix) assert_equal('http://www.w3.org/1999/xlink', attr.ns.href) attr = attributes.get_attribute_ns('http://www.w3.org/1999/xlink', 'href') assert_instance_of(LibXML::XML::Attr, attr) attr = attributes.get_attribute_ns('http://www.opengis.net/gml', 'remoteSchema') assert_instance_of(LibXML::XML::Attr, attr) attr = attributes.get_attribute_ns('http://i.dont.exist', 'nor do i') assert_nil(attr) end def test_get_values assert_equal('Cambridge', city_member[:name]) assert_equal('http://www.foo.net/cgi-bin/wfs?FeatureID=C10239', city_member[:href]) attributes = city_member.attributes assert_equal('Cambridge', attributes[:name]) assert_equal('http://www.foo.net/cgi-bin/wfs?FeatureID=C10239', attributes[:href]) end def test_get_values_gc # There used to be a bug caused by accessing an # attribute over and over and over again. 20000.times do @doc.root.attributes["key"] end end def test_set_values city_member[:name] = 'London' assert_equal('London', city_member[:name]) city_member[:href] = 'foo' assert_equal('foo', city_member[:href]) attributes = city_member.attributes attributes[:name] = 'London' assert_equal('London', attributes[:name]) attributes[:href] = 'foo' assert_equal('foo', attributes[:href]) end def test_str_sym() attributes = city_member.attributes assert_equal('Cambridge', attributes[:name]) assert_equal('Cambridge', attributes['name']) end def test_remove_first attributes = @doc.find_first('/city:CityModel/city:cityMember').attributes assert_equal(5, attributes.length) attr = attributes.first attr.remove! assert_equal(4, attributes.length) end def test_remove_all node = @doc.find_first('/city:CityModel/city:cityMember') assert_equal(5, node.attributes.length) attrs = Array.new node.attributes.each do |attr| attrs << attr attr.remove! end assert_equal(5, attrs.length) assert_equal(0, node.attributes.length) end endlibxml-ruby-3.2.1/test/test_attr.rb0000644000004100000410000001317313760147770017351 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class AttrNodeTest < Minitest::Test def setup xp = LibXML::XML::Parser.string(<<-EOS) City EOS @doc = xp.parse end def teardown @doc = nil end def city_member @doc.find('/city:CityModel/city:cityMember').first end def test_doc refute_nil(@doc) assert_equal(LibXML::XML::Encoding::NONE, @doc.encoding) end def test_types attribute = city_member.attributes.get_attribute('name') assert_instance_of(LibXML::XML::Attr, attribute) assert_equal('attribute', attribute.node_type_name) end def test_name attribute = city_member.attributes.get_attribute('name') assert_equal('name', attribute.name) assert_equal(Encoding::UTF_8, attribute.name.encoding) attribute = city_member.attributes.get_attribute('href') assert_equal('href', attribute.name) assert_equal('xlink', attribute.ns.prefix) assert_equal('http://www.w3.org/1999/xlink', attribute.ns.href) attribute = city_member.attributes.get_attribute_ns('http://www.w3.org/1999/xlink', 'href') assert_equal('href', attribute.name) assert_equal('xlink', attribute.ns.prefix) assert_equal('http://www.w3.org/1999/xlink', attribute.ns.href) end def test_value attribute = city_member.attributes.get_attribute('name') assert_equal('Cambridge', attribute.value) assert_equal(Encoding::UTF_8, attribute.value.encoding) attribute = city_member.attributes.get_attribute('href') assert_equal('http://www.foo.net/cgi-bin/wfs?FeatureID=C10239', attribute.value) end def test_set_value attribute = city_member.attributes.get_attribute('name') attribute.value = 'London' assert_equal('London', attribute.value) assert_equal(Encoding::UTF_8, attribute.value.encoding) attribute = city_member.attributes.get_attribute('href') attribute.value = 'http://i.have.changed' assert_equal('http://i.have.changed', attribute.value) assert_equal(Encoding::UTF_8, attribute.value.encoding) end def test_set_nil attribute = city_member.attributes.get_attribute('name') assert_raises(TypeError) do attribute.value = nil end end def test_create attributes = city_member.attributes assert_equal(5, attributes.length) attr = LibXML::XML::Attr.new(city_member, 'size', '50,000') assert_instance_of(LibXML::XML::Attr, attr) attributes = city_member.attributes assert_equal(6, attributes.length) assert_equal(attributes['size'], '50,000') end def test_create_on_node attributes = city_member.attributes assert_equal(5, attributes.length) attributes['country'] = 'England' attributes = city_member.attributes assert_equal(6, attributes.length) assert_equal(attributes['country'], 'England') end def test_create_ns assert_equal(5, city_member.attributes.length) ns = LibXML::XML::Namespace.new(city_member, 'my_namepace', 'http://www.mynamespace.com') attr = LibXML::XML::Attr.new(city_member, 'rating', 'rocks', ns) assert_instance_of(LibXML::XML::Attr, attr) assert_equal('rating', attr.name) assert_equal('rocks', attr.value) attributes = city_member.attributes assert_equal(6, attributes.length) assert_equal('rocks', city_member['rating']) end def test_remove attributes = city_member.attributes assert_equal(5, attributes.length) attribute = attributes.get_attribute('name') refute_nil(attribute.parent) assert(attribute.parent?) attribute.remove! assert_equal(4, attributes.length) attribute = attributes.get_attribute('name') assert_nil(attribute) end def test_first attribute = city_member.attributes.first assert_instance_of(LibXML::XML::Attr, attribute) assert_equal('name', attribute.name) assert_equal('Cambridge', attribute.value) attribute = attribute.next assert_instance_of(LibXML::XML::Attr, attribute) assert_equal('type', attribute.name) assert_equal('simple', attribute.value) attribute = attribute.next assert_instance_of(LibXML::XML::Attr, attribute) assert_equal('title', attribute.name) assert_equal('Trinity Lane', attribute.value) attribute = attribute.next assert_instance_of(LibXML::XML::Attr, attribute) assert_equal('href', attribute.name) assert_equal('http://www.foo.net/cgi-bin/wfs?FeatureID=C10239', attribute.value) attribute = attribute.next assert_instance_of(LibXML::XML::Attr, attribute) assert_equal('remoteSchema', attribute.name) assert_equal("city.xsd#xpointer(//complexType[@name='RoadType'])", attribute.value) attribute = attribute.next assert_nil(attribute) end def test_no_attributes element = @doc.find('/city:CityModel/city:type').first refute_nil(element.attributes) assert_equal(0, element.attributes.length) end endlibxml-ruby-3.2.1/test/test_xpointer.rb0000644000004100000410000000465313760147770020252 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class TC_XML_XPointer < Minitest::Test def setup() xp = LibXML::XML::Parser.string(']>onetwothree') @doc = xp.parse assert_instance_of(LibXML::XML::Document, @doc) @root = @doc.root assert_instance_of(LibXML::XML::Node, @root) end def teardown() @doc = nil @root = nil @xptr = nil end def test_libxml_xpointer_id xptr = @root.pointer('xpointer(id("two"))') assert_instance_of(LibXML::XML::XPath::Object, xptr) xptr.each do |node| # It seems from the spec that the pointer should # be the whole node, rather than just the ID attr. assert_equal('two', node.content) assert_instance_of(LibXML::XML::Node, node) assert_equal('two', node['id']) end # FIXME: Not sure at all about this kind of range if ENV['NOTWORKING'] @xptr = @root.pointer('xpointer(id("two")) xpointer(id("three"))') assert_instance_of(LibXML::XML::XPath, @xptr) assert_instance_of(LibXML::XML::Node::Set, @xptr.set) assert_equal(2, @xptr.set.length) for n in @xptr.set assert_match(/two|three/, n.to_s) end end end # FIXME: There is a bug in these ranges... if ENV['NOTWORKING'] def test_libxml_xpointer_range() nstart = nend = nil @xptr = @root.pointer('xpointer(id("one"))').set @xptr.each{|n| nstart = n} assert_instance_of(LibXML::XML::Node, nstart) @xptr = @root.pointer('xpointer(id("three"))').set @xptr.each{|n| nend = n} assert_instance_of(LibXML::XML::Node, nend) range = LibXML::XML::XPointer.range(nstart, nend) assert_instance_of(LibXML::XML::XPath, range) assert_instance_of(LibXML::XML::Node::Set, range.set) for n in range.set assert_match(/one|two|three/, n.to_s) end assert_equal(3, range.set.length) end end # def test_libxml_xpointer_start_point() # @xptr = @root.pointer('xpointer(start-point("one"))') # assert_instance_of(LibXML::XML::XPath, @xptr) # set = @xptr.set # assert_instance_of(LibXML::XML::Node::Set, set) # for n in set # assert_match(/one|two|three/, n.to_s) # end # end end libxml-ruby-3.2.1/test/test_dtd.rb0000644000004100000410000001073013760147770017146 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class TestDtd < Minitest::Test def setup xp = LibXML::XML::Parser.string(<<-EOS) Colorado Lots of nice mountains EOS @doc = xp.parse end def teardown @doc = nil end def dtd LibXML::XML::Dtd.new(<<-EOS) EOS end def test_internal_subset xhtml_dtd = LibXML::XML::Dtd.new "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", nil, nil, true assert xhtml_dtd.name.nil? assert_equal "-//W3C//DTD XHTML 1.0 Transitional//EN", xhtml_dtd.external_id assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.uri assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.system_id xhtml_dtd = LibXML::XML::Dtd.new "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", "xhtml1", nil, true assert_equal "xhtml1", xhtml_dtd.name assert_equal "-//W3C//DTD XHTML 1.0 Transitional//EN", xhtml_dtd.external_id assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.uri assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.system_id end def test_external_subset xhtml_dtd = LibXML::XML::Dtd.new "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", nil assert xhtml_dtd.name.nil? assert_equal "-//W3C//DTD XHTML 1.0 Transitional//EN", xhtml_dtd.external_id assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.uri assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.system_id xhtml_dtd = LibXML::XML::Dtd.new "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", "xhtml1" assert_equal "xhtml1", xhtml_dtd.name assert_equal "-//W3C//DTD XHTML 1.0 Transitional//EN", xhtml_dtd.external_id assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.uri assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.system_id end def test_valid assert(@doc.validate(dtd)) end def test_node_type assert_equal(LibXML::XML::Node::DTD_NODE, dtd.node_type) end def test_invalid new_node = LibXML::XML::Node.new('invalid', 'this will mess up validation') @doc.root << new_node error = assert_raises(LibXML::XML::Error) do @doc.validate(dtd) end # Check the error worked refute_nil(error) assert_kind_of(LibXML::XML::Error, error) assert_equal("Error: No declaration for element invalid.", error.message) assert_equal(LibXML::XML::Error::VALID, error.domain) assert_equal(LibXML::XML::Error::DTD_UNKNOWN_ELEM, error.code) assert_equal(LibXML::XML::Error::ERROR, error.level) assert_nil(error.file) assert_nil(error.line) assert_equal('invalid', error.str1) assert_nil(error.str2) assert_nil(error.str3) assert_equal(0, error.int1) assert_equal(0, error.int2) refute_nil(error.node) assert_equal('invalid', error.node.name) end def test_external_dtd xml = <<-EOS T1 EOS errors = Array.new LibXML::XML::Error.set_handler do |error| errors << error end LibXML::XML.default_load_external_dtd = false LibXML::XML::Parser.string(xml).parse assert_equal(0, errors.length) errors.clear LibXML::XML.default_load_external_dtd = true LibXML::XML::Parser.string(xml).parse assert_equal(1, errors.length) assert_equal("Warning: failed to load external entity \"test.dtd\" at :1.", errors[0].to_s) errors = Array.new LibXML::XML::Parser.string(xml, :options => LibXML::XML::Parser::Options::DTDLOAD).parse assert_equal(1, errors.length) assert_equal("Warning: failed to load external entity \"test.dtd\" at :1.", errors[0].to_s) ensure LibXML::XML.default_load_external_dtd = false LibXML::XML::Error.reset_handler end end libxml-ruby-3.2.1/test/test_traversal.rb0000644000004100000410000000611513760147770020400 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class TestTranversal < Minitest::Test ROOT_NODES_LENGTH = 27 ROOT_ELEMENTS_LENGTH = 13 def setup filename = File.join(File.dirname(__FILE__), 'model/books.xml') @doc = LibXML::XML::Document.file(filename) end def teardown @doc = nil end def test_children # Includes text nodes and such assert_equal(ROOT_NODES_LENGTH, @doc.root.children.length) end def test_children_iteration # Includes text nodes and such nodes = @doc.root.children.inject([]) do |arr, node| arr << node arr end assert_equal(ROOT_NODES_LENGTH, nodes.length) end def test_no_children # Get a node with no children node = @doc.find_first('/catalog/book[@id="bk113"]/price') assert_equal(0, node.children.length) end def test_no_children_inner_xml # Get a node with no children node = @doc.find_first('/catalog/book[@id="bk113"]/price') assert_nil(node.inner_xml) end def test_each # Includes text nodes and such nodes = @doc.root.inject([]) do |arr, node| arr << node arr end assert_equal(ROOT_NODES_LENGTH, nodes.length) end def test_each_element # Includes text nodes and such nodes = [] @doc.root.each_element do |node| nodes << node end assert_equal(ROOT_ELEMENTS_LENGTH, nodes.length) end def test_next nodes = [] node = @doc.root.first while node nodes << node node = node.next end assert_equal(ROOT_NODES_LENGTH, nodes.length) end def test_next? first_node = @doc.root.first assert(first_node.next?) last_node = @doc.root.last assert(!last_node.next?) end def test_prev nodes = [] node = @doc.root.last while node nodes << node node = node.prev end assert_equal(ROOT_NODES_LENGTH, nodes.length) end def test_prev? first_node = @doc.root.first assert(!first_node.prev?) last_node = @doc.root.last assert(last_node.prev?) end def test_parent? assert(!@doc.parent?) assert(@doc.root.parent?) end def test_child? assert(@doc.child?) assert(!@doc.root.first.child?) end def test_next_prev_equivalence next_nodes = [] last_nodes = [] node = @doc.root.first while node next_nodes << node node = node.next end node = @doc.root.last while node last_nodes << node node = node.prev end assert_equal(next_nodes, last_nodes.reverse) end def test_next_children_equivalence next_nodes = [] node = @doc.root.first while node next_nodes << node node = node.next end assert_equal(@doc.root.children, next_nodes) end def test_doc_class assert_instance_of(LibXML::XML::Document, @doc) end def test_root_class assert_instance_of(LibXML::XML::Node, @doc.root) end end libxml-ruby-3.2.1/test/test_encoding.rb0000644000004100000410000001127513760147770020166 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' # Code UTF8 Latin1 Hex # m 109 109 6D # ö 195 182 246 C3 B6 / F6 # t 116 116 74 # l 108 108 6C # e 101 101 65 # y 121 121 79 # _ 95 95 5F # c 99 99 63 # r 114 114 72 # ü 195 188 252 C3 BC / FC # e 101 101 65 # See: # http://en.wikipedia.org/wiki/ISO/IEC_8859-1 # http://en.wikipedia.org/wiki/List_of_Unicode_characters class TestEncoding < Minitest::Test def setup @original_encoding = Encoding.default_internal Encoding.default_internal = nil end def teardown Encoding.default_internal = @original_encoding end def file_for_encoding(encoding) file_name = "model/bands.#{encoding.name.downcase}.xml" File.join(File.dirname(__FILE__), file_name) end def load_encoding(encoding) @encoding = encoding file = file_for_encoding(encoding) # Strip spaces to make testing easier LibXML::XML.default_keep_blanks = false @doc = LibXML::XML::Document.file(file) LibXML::XML.default_keep_blanks = true end def test_encoding doc = LibXML::XML::Document.new assert_equal(LibXML::XML::Encoding::NONE, doc.encoding) assert_equal(Encoding::ASCII_8BIT, doc.rb_encoding) file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.xml')) doc = LibXML::XML::Document.file(file) assert_equal(LibXML::XML::Encoding::UTF_8, doc.encoding) assert_equal(Encoding::UTF_8, doc.rb_encoding) doc.encoding = LibXML::XML::Encoding::ISO_8859_1 assert_equal(LibXML::XML::Encoding::ISO_8859_1, doc.encoding) assert_equal(Encoding::ISO8859_1, doc.rb_encoding) end def test_no_internal_encoding_iso_8859_1 load_encoding(Encoding::ISO_8859_1) node = @doc.root.children.first name = node.name assert_equal(Encoding::UTF_8, name.encoding) assert_equal("m\u00F6tley_cr\u00FCe", name) assert_equal("109 195 182 116 108 101 121 95 99 114 195 188 101", name.bytes.to_a.join(" ")) assert_equal("M\u00F6tley Cr\u00FCe is an American heavy metal band formed in Los Angeles, California in 1981.", node.content) name = name.encode(Encoding::ISO_8859_1) assert_equal(Encoding::ISO_8859_1, name.encoding) assert_equal("m\xF6tley_cr\xFCe".force_encoding(Encoding::ISO_8859_1), name) assert_equal("109 246 116 108 101 121 95 99 114 252 101", name.bytes.to_a.join(" ")) assert_equal("M\xF6tley Cr\xFCe is an American heavy metal band formed in Los Angeles, California in 1981.".force_encoding(Encoding::ISO_8859_1), node.content.encode(Encoding::ISO_8859_1)) end def test_internal_encoding_iso_8859_1 Encoding.default_internal = Encoding::ISO_8859_1 load_encoding(Encoding::ISO_8859_1) node = @doc.root.children.first name = node.name assert_equal(Encoding::ISO_8859_1, name.encoding) assert_equal("109 246 116 108 101 121 95 99 114 252 101", name.bytes.to_a.join(" ")) assert_equal("m\xF6tley_cr\xFCe".force_encoding(Encoding::ISO_8859_1), name) assert_equal("109 246 116 108 101 121 95 99 114 252 101", name.bytes.to_a.join(" ")) assert_equal("M\xF6tley Cr\xFCe is an American heavy metal band formed in Los Angeles, California in 1981.".force_encoding(Encoding::ISO_8859_1), node.content.encode(Encoding::ISO_8859_1)) end def test_no_internal_encoding_utf_8 load_encoding(Encoding::UTF_8) node = @doc.root.children.first name = node.name assert_equal(@encoding, name.encoding) assert_equal("109 195 182 116 108 101 121 95 99 114 195 188 101", name.bytes.to_a.join(" ")) name = name.encode(Encoding::ISO_8859_1) assert_equal(Encoding::ISO_8859_1, name.encoding) assert_equal("109 246 116 108 101 121 95 99 114 252 101", name.bytes.to_a.join(" ")) end def test_internal_encoding_utf_8 Encoding.default_internal = Encoding::ISO_8859_1 load_encoding(Encoding::UTF_8) node = @doc.root.children.first name = node.name assert_equal(Encoding::ISO_8859_1, name.encoding) assert_equal("109 246 116 108 101 121 95 99 114 252 101", name.bytes.to_a.join(" ")) end def test_encoding_conversions assert_equal("UTF-8", LibXML::XML::Encoding.to_s(LibXML::XML::Encoding::UTF_8)) assert_equal(LibXML::XML::Encoding::UTF_8, LibXML::XML::Encoding.from_s("UTF-8")) end end libxml-ruby-3.2.1/test/test_relaxng.rb0000644000004100000410000000273513760147770020041 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class TestRelaxNG < Minitest::Test def setup file = File.join(File.dirname(__FILE__), 'model/shiporder.xml') @doc = LibXML::XML::Document.file(file) end def teardown @doc = nil end def relaxng document = LibXML::XML::Document.file(File.join(File.dirname(__FILE__), 'model/shiporder.rng')) LibXML::XML::RelaxNG.document(document) end def test_from_doc assert_instance_of(LibXML::XML::RelaxNG, relaxng) end def test_valid assert(@doc.validate_relaxng(relaxng)) end def test_invalid new_node = LibXML::XML::Node.new('invalid', 'this will mess up validation') @doc.root << new_node error = assert_raises(LibXML::XML::Error) do @doc.validate_relaxng(relaxng) end refute_nil(error) assert_kind_of(LibXML::XML::Error, error) assert(error.message.match(/Error: Did not expect element invalid there/)) assert_equal(LibXML::XML::Error::RELAXNGV, error.domain) assert_equal(LibXML::XML::Error::LT_IN_ATTRIBUTE, error.code) assert_equal(LibXML::XML::Error::ERROR, error.level) assert(error.file.match(/shiporder\.xml/)) assert_nil(error.line) assert_equal('invalid', error.str1) assert_nil(error.str2) assert_nil(error.str3) assert_equal(0, error.int1) assert_equal(0, error.int2) refute_nil(error.node) assert_equal('invalid', error.node.name) end end libxml-ruby-3.2.1/test/test_encoding_sax.rb0000644000004100000410000000610413760147770021034 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class SaxEncodingCallbacks attr_reader :encoding attr_accessor :assertions include Minitest::Assertions def initialize @assertions = 0 @encoding = Encoding::UTF_8 end # Called for a CDATA block event. def on_cdata_block(cdata) assert_equal(self.encoding, cdata.encoding) end # Called for a characters event. def on_characters(chars) assert_equal(self.encoding, chars.encoding) end # Called for a comment event. def on_comment(msg) assert_equal(self.encoding, msg.encoding) end # Called for a end document event. def on_end_document end # Called for a end element event. def on_end_element_ns(name, prefix, uri) assert_equal(self.encoding, name.encoding) assert_equal(self.encoding, prefix.encoding) if prefix assert_equal(self.encoding, uri.encoding) if uri end # Called for parser errors. def on_error(msg) assert_equal(self.encoding, msg.encoding) end # Called for an external subset event. def on_external_subset(name, external_id, system_id) assert_equal(self.encoding, name.encoding) assert_equal(self.encoding, external_id.encoding) assert_equal(self.encoding, system_id.encoding) end # Called for an external subset notification event. def on_has_external_subset end # Called for an internal subset notification event. def on_has_internal_subset end # Called for an internal subset event. def on_internal_subset(name, external_id, system_id) assert_equal(self.encoding, name.encoding) assert_equal(self.encoding, external_id.encoding) assert_equal(self.encoding, system_id.encoding) end # Called for 'is standalone' event. def on_is_standalone end # Called for an processing instruction event. def on_processing_instruction(target, data) assert_equal(self.encoding, target.encoding) assert_equal(self.encoding, data.encoding) end # Called for a reference event. def on_reference(name) assert_equal(self.encoding, name.encoding) end # Called for a start document event. def on_start_document end # Called for a start element event. def on_start_element_ns(name, attributes, prefix, uri, namespaces) assert_equal(self.encoding, name.encoding) if name assert_equal(self.encoding, prefix.encoding) if prefix assert_equal(self.encoding, uri.encoding) if uri end end class TestEncodingSax < Minitest::Test def setup Encoding.default_internal = nil end def file_for_encoding(encoding) file_name = "model/bands.#{encoding.name.downcase}.xml" File.join(File.dirname(__FILE__), file_name) end def test_encoding_iso_8859_1 parser = LibXML::XML::SaxParser.file(file_for_encoding(Encoding::ISO_8859_1)) parser.callbacks = SaxEncodingCallbacks.new parser.parse end def test_encoding_utf8 parser = LibXML::XML::SaxParser.file(file_for_encoding(Encoding::UTF_8)) parser.callbacks = SaxEncodingCallbacks.new parser.parse end endlibxml-ruby-3.2.1/test/test_html_parser.rb0000644000004100000410000001116513760147770020716 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' require 'stringio' class HTMLParserTest < Minitest::Test def html_file File.expand_path(File.join(File.dirname(__FILE__), 'model/ruby-lang.html')) end # ----- Sources ------ def test_file xp = LibXML::XML::HTMLParser.file(html_file) assert_instance_of(LibXML::XML::HTMLParser, xp) doc = xp.parse refute_nil(doc) end def test_noexistent_file error = assert_raises(LibXML::XML::Error) do LibXML::XML::HTMLParser.file('i_dont_exist.xml') end assert_equal('Warning: failed to load external entity "i_dont_exist.xml".', error.to_s) end def test_nil_file error = assert_raises(TypeError) do LibXML::XML::HTMLParser.file(nil) end assert_match(/nil into String/, error.to_s) end def test_io File.open(html_file) do |io| xp = LibXML::XML::HTMLParser.io(io) assert_instance_of(LibXML::XML::HTMLParser, xp) doc = xp.parse assert_instance_of(LibXML::XML::Document, doc) end end def test_io_gc # Test that the reader keeps a reference # to the io object file = File.open(html_file) parser = LibXML::XML::HTMLParser.io(file) file = nil GC.start assert(parser.parse) end def test_nil_io error = assert_raises(TypeError) do LibXML::XML::HTMLParser.io(nil) end assert_equal("Must pass in an IO object", error.to_s) end def test_string_io data = File.read(html_file) io = StringIO.new(data) xp = LibXML::XML::HTMLParser.io(io) assert_instance_of(LibXML::XML::HTMLParser, xp) doc = xp.parse assert_instance_of(LibXML::XML::Document, doc) end def test_string str = '

hi

' xp = LibXML::XML::HTMLParser.string(str) assert_instance_of(LibXML::XML::HTMLParser, xp) assert_instance_of(LibXML::XML::HTMLParser, xp) doc = xp.parse assert_instance_of(LibXML::XML::Document, doc) end def test_nil_string error = assert_raises(TypeError) do LibXML::XML::HTMLParser.string(nil) end assert_equal("wrong argument type nil (expected String)", error.to_s) end def test_parse html = <<-EOS Hello
World EOS parser = LibXML::XML::HTMLParser.string(html, :options => LibXML::XML::HTMLParser::Options::NOBLANKS) doc = parser.parse assert_instance_of LibXML::XML::Document, doc root = doc.root assert_instance_of LibXML::XML::Node, root assert_equal 'html', root.name head = root.child assert_instance_of LibXML::XML::Node, head assert_equal 'head', head.name meta = head.child assert_instance_of LibXML::XML::Node, meta assert_equal 'meta', meta.name assert_equal 'keywords', meta[:name] assert_equal 'nasty', meta[:content] body = head.next assert_instance_of LibXML::XML::Node, body assert_equal 'body', body.name hello = body.child # It appears that some versions of libxml2 add a layer of

# cant figure our why or how, so this skips it if there hello = hello.child if hello.name == "p" assert_instance_of LibXML::XML::Node, hello assert_equal 'Hello', hello.content br = hello.next assert_instance_of LibXML::XML::Node, br assert_equal 'br', br.name world = br.next assert_instance_of LibXML::XML::Node, world assert_equal 'World', world.content end def test_no_implied html = "hello world" parser = LibXML::XML::HTMLParser.string(html, :options => LibXML::XML::HTMLParser::Options::NOIMPLIED) doc = parser.parse assert_equal("

#{html}

", doc.root.to_s) end def test_comment doc = LibXML::XML::HTMLParser.string('', :options => LibXML::XML::HTMLParser::Options::NOIMPLIED | LibXML::XML::HTMLParser::Options::NOERROR | LibXML::XML::HTMLParser::Options::NOWARNING | LibXML::XML::HTMLParser::Options::RECOVER | LibXML::XML::HTMLParser::Options::NONET) assert(doc) end def test_open_many_files file = File.expand_path(File.join(File.dirname(__FILE__), 'model/ruby-lang.html')) 1000.times do LibXML::XML::HTMLParser.file(file).parse end end end libxml-ruby-3.2.1/test/test_node.rb0000644000004100000410000001446413760147770017330 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class TestNode < Minitest::Test def setup @file_name = "model/bands.utf-8.xml" # Strip spaces to make testing easier LibXML::XML.default_keep_blanks = false file = File.join(File.dirname(__FILE__), @file_name) @doc = LibXML::XML::Document.file(file) end def teardown LibXML::XML.default_keep_blanks = true @doc = nil end def nodes # Find all nodes with a country attributes @doc.find('*[@country]') end def test_doc_class assert_instance_of(LibXML::XML::Document, @doc) end def test_doc_node_type assert_equal LibXML::XML::Node::DOCUMENT_NODE, @doc.node_type end def test_root_class assert_instance_of(LibXML::XML::Node, @doc.root) end def test_root_node_type assert_equal LibXML::XML::Node::ELEMENT_NODE, @doc.root.node_type end def test_node_class for n in nodes assert_instance_of(LibXML::XML::Node, n) end end def test_context node = @doc.root context = node.context assert_instance_of(LibXML::XML::XPath::Context, context) end def test_find assert_instance_of(LibXML::XML::XPath::Object, self.nodes) end def test_node_child_get assert_instance_of(TrueClass, @doc.root.child?) assert_instance_of(LibXML::XML::Node, @doc.root.child) assert_equal(Encoding::UTF_8, @doc.root.child.name.encoding) assert_equal("m\u00F6tley_cr\u00FCe", @doc.root.child.name) end def test_node_doc for n in nodes assert_instance_of(LibXML::XML::Document, n.doc) if n.document? end end def test_name node = @doc.root.children.last assert_equal("iron_maiden", node.name) end def test_node_find nodes = @doc.root.find('./fixnum') for node in nodes assert_instance_of(LibXML::XML::Node, node) end end def test_equality node_a = @doc.find_first('*[@country]') node_b = @doc.root.child # On the ruby side these are different objects refute(node_a.equal?(node_b)) # But they are the same underlying libxml node so specify they are equal assert(node_a == node_b) assert(node_a.eql?(node_b)) file = File.join(File.dirname(__FILE__), @file_name) doc2 = LibXML::XML::Document.file(file) node_a2 = doc2.find_first('*[@country]') refute(node_a == node_a2) refute(node_a.eql?(node_a2)) assert_equal(node_a.to_s, node_a2.to_s) refute(node_a.equal?(node_a2)) end def test_equality_2 parent = LibXML::XML::Node.new('parent') child = LibXML::XML::Node.new('child') parent << child node_a = child.parent node_b = child.parent # In this case the nodes are equal - the parent being the root assert(node_a.equal?(node_b)) assert(node_a == node_b) assert(node_a.eql?(node_b)) end def test_equality_nil node = @doc.root assert(node != nil) end def test_equality_wrong_type node = @doc.root assert_raises(TypeError) do assert(node != 'abc') end end def test_content node = @doc.root.last assert_equal("Iron Maiden is a British heavy metal band formed in 1975.", node.content) end def test_base doc = LibXML::XML::Parser.string('').parse assert_nil(doc.root.base_uri) end # We use the same facility that libXSLT does here to disable output escaping. # This lets you specify that the node's content should be rendered unaltered # whenever it is being output. This is useful for things like libxml-ruby-3.2.1/test/model/bands.utf-8.xml0000644000004100000410000000046413760147770020665 0ustar www-datawww-data Mötley Crüe is an American heavy metal band formed in Los Angeles, California in 1981. Iron Maiden is a British heavy metal band formed in 1975. libxml-ruby-3.2.1/test/model/shiporder.rng0000644000004100000410000000371513760147770020623 0ustar www-datawww-data libxml-ruby-3.2.1/test/model/xinclude.xml0000644000004100000410000000034213760147770020442 0ustar www-datawww-data

This libxml2 binding has the following project information:

libxml-ruby-3.2.1/test/model/soap.xml0000644000004100000410000000227113760147770017574 0ustar www-datawww-data 1 man1 2 man2 3 man3 libxml-ruby-3.2.1/test/model/shiporder.xsd0000644000004100000410000000310713760147770020626 0ustar www-datawww-data Shiporder type documentation orderperson element documentation libxml-ruby-3.2.1/test/model/shiporder.xml0000644000004100000410000000122113760147770020623 0ustar www-datawww-data John Smith Ola Nordmann
Langgt 23
4000 Stavanger Norway
Empire Burlesque Special Edition 1 10.90 Hide your heart 1 9.90
libxml-ruby-3.2.1/test/model/atom.xml0000644000004100000410000000065413760147770017575 0ustar www-datawww-data <![CDATA[<<strong>>]]> hi there libxml-ruby-3.2.1/test/model/rubynet.xml0000644000004100000410000000610313760147770020320 0ustar www-datawww-data REXML Aaron Malone aaron@munge.net irc.opentprojects.org #ruby-lang AAmalone Tools Team tools@gentoo.org irc.opentprojects.org #ruby-lang TinyT XML Text Processing Storage 1 2 3 1999-2002 Gentoo Technologies,Inc. Ruby Stable Ruby Electric XML Pure Ruby parser, blah blah. Based of Electrice XML REXML Home REXML Download 1 6 0 uga.rb 0444 ... the file here booga.h 0444 ... the file here foo.so 0555 Li4uIHRoZSBmaWxlIGhlcmU=\n libxml-ruby-3.2.1/test/model/bands.iso-8859-1.xml0000644000004100000410000000046313760147770021264 0ustar www-datawww-data Mötley Crüe is an American heavy metal band formed in Los Angeles, California in 1981. Iron Maiden is a British heavy metal band formed in 1975. libxml-ruby-3.2.1/test/test_node_write.rb0000644000004100000410000001070713760147770020536 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class TestNodeWrite < Minitest::Test def setup load_encoding("utf-8") end def teardown LibXML::XML.default_keep_blanks = true @doc = nil end def load_encoding(name) @encoding = Encoding.find(name) @file_name = "model/bands.#{name.downcase}.xml" # Strip spaces to make testing easier LibXML::XML.default_keep_blanks = false file = File.join(File.dirname(__FILE__), @file_name) @doc = LibXML::XML::Document.file(file) end def test_to_s_default # Default to_s has indentation node = @doc.root assert_equal(Encoding::UTF_8, node.to_s.encoding) assert_equal("\n M\303\266tley Cr\303\274e is an American heavy metal band formed in Los Angeles, California in 1981.\n Iron Maiden is a British heavy metal band formed in 1975.\n", node.to_s) end def test_to_s_no_global_indentation # No indentation due to global setting node = @doc.root LibXML::XML.indent_tree_output = false assert_equal("\nM\303\266tley Cr\303\274e is an American heavy metal band formed in Los Angeles, California in 1981.\nIron Maiden is a British heavy metal band formed in 1975.\n", node.to_s) ensure LibXML::XML.indent_tree_output = true end def test_to_s_no_indentation # No indentation due to local setting node = @doc.root assert_equal("M\303\266tley Cr\303\274e is an American heavy metal band formed in Los Angeles, California in 1981.Iron Maiden is a British heavy metal band formed in 1975.", node.to_s(:indent => false)) end def test_to_s_level # No indentation due to local setting node = @doc.root assert_equal("\n M\303\266tley Cr\303\274e is an American heavy metal band formed in Los Angeles, California in 1981.\n Iron Maiden is a British heavy metal band formed in 1975.\n ", node.to_s(:level => 1)) end def test_to_s_encoding # Test encodings node = @doc.root # UTF8: # ö - c3 b6 in hex, \303\266 in octal # ü - c3 bc in hex, \303\274 in octal value = node.to_s(:encoding => LibXML::XML::Encoding::UTF_8) assert_equal(Encoding::UTF_8, node.to_s.encoding) assert_equal("\n M\303\266tley Cr\303\274e is an American heavy metal band formed in Los Angeles, California in 1981.\n Iron Maiden is a British heavy metal band formed in 1975.\n", value) # ISO_8859_1: # ö - f6 in hex, \366 in octal # ü - fc in hex, \374 in octal value = node.to_s(:encoding => LibXML::XML::Encoding::ISO_8859_1) assert_equal(Encoding::ISO8859_1, value.encoding) assert_equal("\n M\xF6tley Cr\xFCe is an American heavy metal band formed in Los Angeles, California in 1981.\n Iron Maiden is a British heavy metal band formed in 1975.\n".force_encoding(Encoding::ISO8859_1), value) # Invalid encoding error = assert_raises(ArgumentError) do node.to_s(:encoding => -9999) end assert_equal('Unknown encoding value: -9999', error.to_s) end def test_inner_xml # Default to_s has indentation node = @doc.root assert_equal(Encoding::UTF_8, node.inner_xml.encoding) assert_equal("M\u00F6tley Cr\u00FCe is an American heavy metal band formed in Los Angeles, California in 1981.Iron Maiden is a British heavy metal band formed in 1975.", node.inner_xml) end # --- Debug --- def test_debug assert(@doc.root.debug) end endlibxml-ruby-3.2.1/test/test_error.rb0000644000004100000410000001366413760147770017535 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' require 'stringio' class TestError < Minitest::Test # def test_error_codes # assert_equal(4, LibXML::XML::Error::DTD) # assert_equal(4, LibXML::XML::Error.const_get('DTD')) # # assert_equal(4, LibXML::XML::Error::DOCUMENT_EMPTY) # assert_equal(4, LibXML::XML::Error.const_get('DOCUMENT_EMPTY')) # end # # def test_invalid_handler # assert_raises(RuntimeError) do # LibXML::XML::Error.set_handler # end # end # # def test_handler # exception = nil # LibXML::XML::Error.set_handler do |error| # exception = error # end # # # Raise the error # error = assert_raises(LibXML::XML::Error) do # LibXML::XML::Reader.string('').parse # end # ensure # Object.const_set(:STDERR, original_stderr) # end # assert_equal("Fatal error: Opening and ending tag mismatch: foo line 1 and foz at :1.\n", output.string) # end # # def test_no_hanlder # LibXML::XML::Error.reset_handler # output = StringIO.new # original_stderr = Object::STDERR # # Object.const_set(:STDERR, output) # begin # assert_raises(LibXML::XML::Error) do # LibXML::XML::Parser.string('').parse # end # ensure # Object.const_set(:STDERR, original_stderr) # end # assert_equal('', output.string) # end # # def test_parse_error # exception = assert_raises(LibXML::XML::Error) do # LibXML::XML::Parser.string('').parse # end # # assert_instance_of(LibXML::XML::Error, exception) # assert_equal("Fatal error: Opening and ending tag mismatch: foo line 1 and foz at :1.", exception.message) # assert_equal(LibXML::XML::Error::PARSER, exception.domain) # assert_equal(LibXML::XML::Error::TAG_NAME_MISMATCH, exception.code) # assert_equal(LibXML::XML::Error::FATAL, exception.level) # assert_nil(exception.file) # assert_equal(1, exception.line) # end # # def test_xpath_error # doc = LibXML::XML::Document.file(File.join(File.dirname(__FILE__), 'model/soap.xml')) # # exception = assert_raises(LibXML::XML::Error) do # doc.find('/foo[bar=test') # end # # assert_instance_of(LibXML::XML::Error, exception) # assert_equal("Error: Invalid predicate.", exception.message) # assert_equal(LibXML::XML::Error::XPATH, exception.domain) # assert_equal(LibXML::XML::Error::XPATH_INVALID_PREDICATE_ERROR, exception.code) # assert_equal(LibXML::XML::Error::ERROR, exception.level) # assert_nil(exception.file) # assert_nil(nil) # end def test_double_parse LibXML::XML::Parser.register_error_handler(lambda {|msg| nil }) parser = LibXML::XML::Parser.string("something") parser.parse error = assert_raises(LibXML::XML::Error) do # Try parsing a second time parser.parse end assert_equal(" LibXML::XML::Error.", error.to_s) end # def test_libxml_parser_empty_string # xp = LibXML::XML::Parser.new # # error = assert_raises(TypeError) do # xp.string = nil # end # assert_equal('wrong argument type nil (expected String)', error.to_s) # # error = assert_raises(ArgumentError) do # xp.string = '' # end # assert_equal('Must specify a string with one or more characters', error.to_s) # end # # def test_error_domain_to_s # exception = assert_raises(LibXML::XML::Error) do # LibXML::XML::Parser.string('').parse # end # # assert_equal(LibXML::XML::Error::PARSER, exception.domain) # assert_equal("PARSER",exception.domain_to_s) # end # # def test_error_code_to_s # exception = assert_raises(LibXML::XML::Error) do # LibXML::XML::Parser.string('').parse # end # assert_equal(LibXML::XML::Error::ENTITYREF_SEMICOL_MISSING, exception.code) # assert_equal("ENTITYREF_SEMICOL_MISSING",exception.code_to_s) # end end libxml-ruby-3.2.1/test/test_xinclude.rb0000644000004100000410000000126613760147770020212 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class TestXInclude < Minitest::Test def setup @doc = LibXML::XML::Document.file(File.join(File.dirname(__FILE__), 'model/xinclude.xml')) assert_instance_of(LibXML::XML::Document, @doc) end def teardown @doc = nil end def test_ruby_xml_xinclude assert_equal(1, @doc.xinclude) assert_equal("\n\n

This libxml2 binding has the following project information:\n This is some text to include in an xml file via XInclude.

\n
\n", @doc.to_s) end end libxml-ruby-3.2.1/test/test_attr_decl.rb0000644000004100000410000000744413760147770020344 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class AttrDeclTest < Minitest::Test def setup xp = LibXML::XML::Parser.string(<<-EOS) ]> EOS @doc = xp.parse end def teardown @doc = nil end def test_attributes # Get a element with an access attribute elem = @doc.find_first('/root/property[@name="readonly"]') assert_equal(2, elem.attributes.length) refute_nil(elem['access']) # Get a element node without a access attribute elem = @doc.find_first('/root/property[@name="readwrite"]') assert_equal(1, elem.attributes.length) assert_nil(elem['access']) end def test_attr # Get a property node without a access attribute elem = @doc.find_first('/root/property[@name="readonly"]') # Get the attr_decl attr = elem.attributes.get_attribute('access') refute_nil(attr) assert_equal(LibXML::XML::Node::ATTRIBUTE_NODE, attr.node_type) assert_equal('attribute', attr.node_type_name) # Get its value assert_equal('r', attr.value) end def test_attr_decl # Get a property node without a access attribute elem = @doc.find_first('/root/property[@name="readwrite"]') # Get the attr_decl attr_decl = elem.attributes.get_attribute('access') refute_nil(attr_decl) assert_equal(LibXML::XML::Node::ATTRIBUTE_DECL, attr_decl.node_type) assert_equal('attribute declaration', attr_decl.node_type_name) # Get its value assert_equal('rw', attr_decl.value) end def test_type # Get a property node without a access attribute elem = @doc.find_first('/root/property[@name="readwrite"]') attr_decl = elem.attributes.get_attribute('access') refute_nil(attr_decl) assert_equal(LibXML::XML::Node::ATTRIBUTE_DECL, attr_decl.node_type) assert_equal('attribute declaration', attr_decl.node_type_name) end def test_name elem = @doc.find_first('/root/property[@name="readwrite"]') attr_decl = elem.attributes.get_attribute('access') assert_equal('access', attr_decl.name) end def test_value elem = @doc.find_first('/root/property[@name="readwrite"]') attr_decl = elem.attributes.get_attribute('access') assert_equal('rw', attr_decl.value) end def test_to_s elem = @doc.find_first('/root/property[@name="readwrite"]') attr_decl = elem.attributes.get_attribute('access') assert_equal('access = rw', attr_decl.to_s) end def test_prev elem = @doc.find_first('/root/property[@name="readwrite"]') attr_decl = elem.attributes.get_attribute('access') first_decl = attr_decl.prev assert_equal(LibXML::XML::Node::ATTRIBUTE_DECL, first_decl.node_type) assert_equal('name', first_decl.name) assert_nil(first_decl.value) elem_decl = first_decl.prev assert_equal(LibXML::XML::Node::ELEMENT_DECL, elem_decl.node_type) end def test_next elem = @doc.find_first('/root/property[@name="readwrite"]') attr_decl = elem.attributes.get_attribute('access') next_decl = attr_decl.next assert_nil(next_decl) end def test_doc elem = @doc.find_first('/root/property[@name="readwrite"]') attr_decl = elem.attributes.get_attribute('access') assert_same(@doc, attr_decl.doc) end def test_parent elem = @doc.find_first('/root/property[@name="readwrite"]') attr_decl = elem.attributes.get_attribute('access') parent = attr_decl.parent assert_instance_of(LibXML::XML::Dtd, parent) end endlibxml-ruby-3.2.1/test/test.xml0000644000004100000410000000007613760147770016512 0ustar www-datawww-data François libxml-ruby-3.2.1/test/test_node_pi.rb0000644000004100000410000000173213760147770020012 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class NodePiTest < Minitest::Test def setup xp = LibXML::XML::Parser.string('') @doc = xp.parse assert_instance_of(LibXML::XML::Document, @doc) @root = @doc.root end def test_libxml_node_add_pi_01 @root << LibXML::XML::Node.new_pi('mypi') assert_equal '', @root.to_s.gsub(/\n\s*/,'') end def test_libxml_node_add_pi_02 @root << LibXML::XML::Node.new_pi('mypi') assert_equal 'pi', @root.child.node_type_name end def test_libxml_node_add_pi_03 @root << el = LibXML::XML::Node.new_pi('mypi') el << "_this_is_added" assert_equal '', @root.to_s.gsub(/\n\s*/,'') end def test_libxml_node_add_pi_04 @root << LibXML::XML::Node.new_pi('mypi','mycontent') assert_equal '', @root.to_s.gsub(/\n\s*/,'') end end libxml-ruby-3.2.1/test/test_document_write.rb0000644000004100000410000001632713760147770021433 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' require 'tmpdir' class TestDocumentWrite < Minitest::Test def setup @file_name = "model/bands.utf-8.xml" # Strip spaces to make testing easier LibXML::XML.default_keep_blanks = false file = File.join(File.dirname(__FILE__), @file_name) @doc = LibXML::XML::Document.file(file) end def teardown LibXML::XML.default_keep_blanks = true @doc = nil end # --- to_s tests --- def test_to_s_default # Default to_s has indentation assert_equal("\n\n M\u00F6tley Cr\u00FCe is an American heavy metal band formed in Los Angeles, California in 1981.\n Iron Maiden is a British heavy metal band formed in 1975.\n\n", @doc.to_s) end def test_to_s_no_global_indentation # No indentation due to global setting LibXML::XML.indent_tree_output = false value = @doc.to_s assert_equal(Encoding::UTF_8, value.encoding) assert_equal("\n\nM\u00F6tley Cr\u00FCe is an American heavy metal band formed in Los Angeles, California in 1981.\nIron Maiden is a British heavy metal band formed in 1975.\n\n", value) ensure LibXML::XML.indent_tree_output = true end def test_to_s_no_indentation # No indentation due to local setting value = @doc.to_s(:indent => false) assert_equal(Encoding::UTF_8, value.encoding) assert_equal("\nM\u00F6tley Cr\u00FCe is an American heavy metal band formed in Los Angeles, California in 1981.Iron Maiden is a British heavy metal band formed in 1975.\n", value) end def test_to_s_encoding # Test encodings # UTF8: # ö - c3 b6 in hex, \303\266 in octal # ü - c3 bc in hex, \303\274 in octal value = @doc.to_s(:encoding => LibXML::XML::Encoding::UTF_8) assert_equal(Encoding::UTF_8, value.encoding) assert_equal("\n\n M\u00F6tley Cr\u00FCe is an American heavy metal band formed in Los Angeles, California in 1981.\n Iron Maiden is a British heavy metal band formed in 1975.\n\n", value) # ISO_8859_1: # ö - f6 in hex, \366 in octal # ü - fc in hex, \374 in octal value = @doc.to_s(:encoding => LibXML::XML::Encoding::ISO_8859_1) assert_equal(Encoding::ISO8859_1, value.encoding) assert_equal("\n\n M\xF6tley Cr\xFCe is an American heavy metal band formed in Los Angeles, California in 1981.\n Iron Maiden is a British heavy metal band formed in 1975.\n\n".force_encoding(Encoding::ISO8859_1), @doc.to_s(:encoding => LibXML::XML::Encoding::ISO_8859_1)) # Invalid encoding error = assert_raises(ArgumentError) do @doc.to_s(:encoding => -9999) end assert_equal('Unknown encoding value: -9999', error.to_s) end # --- save tests ----- def test_save_utf8 temp_filename = File.join(Dir.tmpdir, "tc_document_write_test_save_utf8.xml") bytes = @doc.save(temp_filename) assert_equal(305, bytes) contents = File.read(temp_filename, nil, nil, :encoding => Encoding::UTF_8) assert_equal(Encoding::UTF_8, contents.encoding) assert_equal("\n\n M\u00F6tley Cr\u00FCe is an American heavy metal band formed in Los Angeles, California in 1981.\n Iron Maiden is a British heavy metal band formed in 1975.\n\n", contents) ensure File.delete(temp_filename) end def test_save_utf8_no_indents temp_filename = File.join(Dir.tmpdir, "tc_document_write_test_save_utf8_no_indents.xml") bytes = @doc.save(temp_filename, :indent => false) assert_equal(298, bytes) contents = File.read(temp_filename, nil, nil, :encoding => Encoding::UTF_8) assert_equal("\nM\u00F6tley Cr\u00FCe is an American heavy metal band formed in Los Angeles, California in 1981.Iron Maiden is a British heavy metal band formed in 1975.\n", contents) ensure File.delete(temp_filename) end def test_save_iso_8859_1 temp_filename = File.join(Dir.tmpdir, "tc_document_write_test_save_iso_8859_1.xml") bytes = @doc.save(temp_filename, :encoding => LibXML::XML::Encoding::ISO_8859_1) assert_equal(304, bytes) contents = File.read(temp_filename, nil, nil, :encoding => Encoding::ISO8859_1) assert_equal(Encoding::ISO8859_1, contents.encoding) assert_equal("\n\n M\xF6tley Cr\xFCe is an American heavy metal band formed in Los Angeles, California in 1981.\n Iron Maiden is a British heavy metal band formed in 1975.\n\n".force_encoding(Encoding::ISO8859_1), contents) ensure File.delete(temp_filename) end def test_save_iso_8859_1_no_indent temp_filename = File.join(Dir.tmpdir, "tc_document_write_test_save_iso_8859_1_no_indent.xml") bytes = @doc.save(temp_filename, :indent => false, :encoding => LibXML::XML::Encoding::ISO_8859_1) assert_equal(297, bytes) contents = File.read(temp_filename, nil, nil, :encoding => Encoding::ISO8859_1) assert_equal(Encoding::ISO8859_1, contents.encoding) assert_equal("\nM\xF6tley Cr\xFCe is an American heavy metal band formed in Los Angeles, California in 1981.Iron Maiden is a British heavy metal band formed in 1975.\n".force_encoding(Encoding::ISO8859_1), contents) ensure File.delete(temp_filename) end def test_thread_set_root # Previously a segmentation fault occurred when running libxml in # background threads. thread = Thread.new do 100000.times do |i| document = LibXML::XML::Document.new node = LibXML::XML::Node.new('test') document.root = node end end thread.join assert(true) end # --- Debug --- def test_debug assert(@doc.debug) end endlibxml-ruby-3.2.1/test/test_xpath.rb0000644000004100000410000002024613760147770017522 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' require 'tempfile' class TestXPath < Minitest::Test def setup @doc = LibXML::XML::Document.file(File.join(File.dirname(__FILE__), 'model/soap.xml')) end def teardown @doc = nil end def test_doc_find nodes = @doc.find('/soap:Envelope') assert_instance_of(LibXML::XML::XPath::Object, nodes) assert_equal(1, nodes.length) assert_equal(nodes.xpath_type, LibXML::XML::XPath::NODESET) end def test_doc_find_first node = @doc.find_first('/soap:Envelope/soap:Body') assert_instance_of(LibXML::XML::Node, node) end def test_ns nodes = @doc.find('//ns1:IdAndName', 'ns1:http://domain.somewhere.com') assert_equal(3, nodes.length) end def test_ns_gc _stress = GC.stress GC.stress = true doc = LibXML::XML::Document.string('') node = doc.root # This line segfaults on prior versions of libxml-ruby node.find("namespace::*") GC.stress = _stress end def test_ns_array nodes = @doc.find('//ns1:IdAndName', ['ns1:http://domain.somewhere.com']) assert_equal(3, nodes.length) end def test_default_ns1 # Find all nodes with http://services.somewhere.com namespace nodes = @doc.find('//*[namespace-uri()="http://services.somewhere.com"]') assert_equal(2, nodes.length) assert_equal('getManufacturerNamesResponse', nodes[0].name) assert_equal('IDAndNameList', nodes[1].name) end def test_default_ns2 # Find all nodes with http://services.somewhere.com namespace nodes = @doc.find('//ns:*', 'ns:http://services.somewhere.com') assert_equal(2, nodes.length) assert_equal('getManufacturerNamesResponse', nodes[0].name) assert_equal('IDAndNameList', nodes[1].name) # Get getManufacturerNamesResponse node nodes = @doc.find('//ns:getManufacturerNamesResponse', 'ns:http://services.somewhere.com') assert_equal(1, nodes.length) # Get IdAndName node nodes = @doc.find('/soap:Envelope/soap:Body/ns0:getManufacturerNamesResponse/ns0:IDAndNameList/ns1:IdAndName', ['ns0:http://services.somewhere.com', 'ns1:http://domain.somewhere.com']) assert_equal(3, nodes.length) end def test_default_ns3 # Find all nodes with http://services.somewhere.com namespace nodes = @doc.find('//ns:*', 'ns' => 'http://services.somewhere.com') assert_equal(2, nodes.length) assert_equal('getManufacturerNamesResponse', nodes[0].name) assert_equal('IDAndNameList', nodes[1].name) end def test_default_ns4 # Find all nodes with http://services.somewhere.com namespace nodes = @doc.find('//ns:*', :ns => 'http://services.somewhere.com') assert_equal(2, nodes.length) assert_equal('getManufacturerNamesResponse', nodes[0].name) assert_equal('IDAndNameList', nodes[1].name) end def test_default_ns5 # Find all nodes with http://services.somewhere.com namespace LibXML::XML::Namespace.new(@doc.root, 'ns', 'http://services.somewhere.com') nodes = @doc.find('//ns:*') assert_equal(2, nodes.length) assert_equal('getManufacturerNamesResponse', nodes[0].name) assert_equal('IDAndNameList', nodes[1].name) end def test_attribute_ns # Pull all nodes with http://services.somewhere.com namespace nodes = @doc.find('@soap:encodingStyle') assert_equal(1, nodes.length) assert_equal('encodingStyle', nodes.first.name) assert_equal('http://www.w3.org/2001/12/soap-encoding', nodes.first.value) end def test_register_default_ns doc = LibXML::XML::Document.file(File.join(File.dirname(__FILE__), 'model/atom.xml')) # No namespace has been yet defined assert_raises(LibXML::XML::Error) do doc.find("atom:title") end node = doc.find('atom:title', 'atom:http://www.w3.org/2005/Atom') refute_nil(node) # Register namespace doc.root.namespaces.default_prefix = 'atom' node = doc.find("atom:title") refute_nil(node) end def test_node_find nodes = @doc.find('//ns1:IdAndName', 'ns1:http://domain.somewhere.com') node = nodes.first # Since we are searching on the node, don't have to register namespace nodes = node.find('ns1:name') assert_equal(1, nodes.length) refute_equal(nodes.first.object_id, nodes.last.object_id) assert_equal('name', nodes.first.name) assert_equal('man1', nodes.first.content) end def test_node_find_first node = @doc.find_first('//ns1:IdAndName', 'ns1:http://domain.somewhere.com') # Since we are searching on the node, don't have to register namespace node = node.find_first('ns1:name') assert_equal('name', node.name) assert_equal('man1', node.content) end def test_node_no_doc node = LibXML::XML::Node.new('header', 'some content') assert_raises(TypeError) do node = node.find_first('/header') end end def test_memory # This sometimes causes a segmentation fault because # an xml document is sometimes freed before the # xpath_object used to query it. When the xpath_object # is free, it iterates over its results which are pointers # to the document's nodes. A segmentation fault then happens. 1000.times do doc = LibXML::XML::Document.new('1.0') doc.root = LibXML::XML::Node.new("header") 1000.times do doc.root << LibXML::XML::Node.new("footer") end doc.find('/header/footer') end end # Test that document doesn't get freed before nodes def test_xpath_free doc = LibXML::XML::Document.file(File.join(File.dirname(__FILE__), 'model/soap.xml')) nodes = doc.find('//*') GC.start assert_equal('Envelope', nodes.first.name) end def test_xpath_namespace_nodes doc = LibXML::XML::Document.string('') nodes = doc.find('//atom:entry|namespace::*', :atom => "http://www.w3.org/2005/Atom") assert_equal(4, nodes.length) node = nodes[0] assert_equal(LibXML::XML::Node::ELEMENT_NODE, node.node_type) node = nodes[1] assert_equal(LibXML::XML::Node::NAMESPACE_DECL, node.node_type) node = nodes[2] assert_equal(LibXML::XML::Node::NAMESPACE_DECL, node.node_type) node = nodes[3] assert_equal(LibXML::XML::Node::NAMESPACE_DECL, node.node_type) end # Test to make sure we don't get nil on empty results. # This is also to test that we don't segfault due to our C code getting a NULL pointer # and not handling it properly. def test_xpath_empty_result doc = LibXML::XML::Document.string('

Welcome to XHTML land!

') nodes = doc.find("//object/param[translate(@name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = 'wmode']") refute_nil nodes end def test_invalid_expression xml = LibXML::XML::Document.string('') # Using the expression twice used to cause a Segmentation Fault error = assert_raises(LibXML::XML::Error) do xml.find('//a/') end assert_equal("Error: Invalid expression.", error.to_s) # Try again - this used to cause a Segmentation Fault error = assert_raises(LibXML::XML::Error) do xml.find('//a/') end assert_equal("Error: Invalid expression.", error.to_s) end def test_find_cdata doc = LibXML::XML::Document.string('hi there bye!') nodes = doc.find('/root/text()') assert_equal(3, nodes.length) assert_equal(nodes[0].node_type, LibXML::XML::Node::TEXT_NODE) assert_equal(nodes[0].content, 'hi there ') assert_equal(nodes[1].node_type, LibXML::XML::Node::CDATA_SECTION_NODE) assert_equal(nodes[1].content, ' mycdata ') assert_equal(nodes[2].node_type, LibXML::XML::Node::TEXT_NODE) assert_equal(nodes[2].content, ' bye!') end def test_find_comment doc = LibXML::XML::Document.string('hi there bye!') nodes = doc.find('//comment()') assert_equal(1, nodes.length) assert_equal(nodes[0].content, ' my comment ') end end libxml-ruby-3.2.1/test/test_node_copy.rb0000644000004100000410000000160613760147770020354 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' # see mailing list archive # [libxml-devel] Segmentation fault when add the cloned/copied node # 2007/11/27 20:51 class TestNodeCopy < Minitest::Test def setup str = <<-STR
foo
bar
STR doc = LibXML::XML::Parser.string(str).parse xpath = "//div" @div1 = doc.find(xpath).to_a[0] @div2 = doc.find(xpath).to_a[1] end def test_libxml_node_copy_not_segv @div2.each do |child| c = child.copy(false) @div1 << c end assert @div1.to_s =~ /foo/ end def test_libxml_node_clone_not_segv @div2.each do |child| c = child.clone @div1 << c end assert @div1.to_s =~ /foo/ end end libxml-ruby-3.2.1/test/test_parser.rb0000644000004100000410000002357213760147770017677 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' require 'stringio' class TestParser < Minitest::Test def setup LibXML::XML::Error.set_handler(&LibXML::XML::Error::QUIET_HANDLER) end # ----- Sources ------- def test_document file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml')) parser = LibXML::XML::Parser.file(file) doc = parser.parse parser = LibXML::XML::Parser.document(doc) doc = parser.parse assert_instance_of(LibXML::XML::Document, doc) assert_instance_of(LibXML::XML::Parser::Context, parser.context) end def test_nil_document error = assert_raises(TypeError) do LibXML::XML::Parser.document(nil) end assert_equal("Must pass an LibXML::XML::Document object", error.to_s) end def test_file file = File.expand_path(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) parser = LibXML::XML::Parser.file(file) doc = parser.parse assert_instance_of(LibXML::XML::Document, doc) assert_instance_of(LibXML::XML::Parser::Context, parser.context) end def test_noexistent_file error = assert_raises(LibXML::XML::Error) do LibXML::XML::Parser.file('i_dont_exist.xml') end assert_equal('Warning: failed to load external entity "i_dont_exist.xml".', error.to_s) end def test_nil_file error = assert_raises(TypeError) do LibXML::XML::Parser.file(nil) end assert_match(/nil into String/, error.to_s) end def test_file_encoding file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml')) parser = LibXML::XML::Parser.file(file, :encoding => LibXML::XML::Encoding::ISO_8859_1) error = assert_raises(LibXML::XML::Error) do parser.parse end assert(error.to_s.match(/Fatal error: Extra content at the end of the document/)) parser = LibXML::XML::Parser.file(file, :encoding => LibXML::XML::Encoding::UTF_8) doc = parser.parse refute_nil(doc) end def test_file_base_uri file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml')) parser = LibXML::XML::Parser.file(file) doc = parser.parse assert(doc.child.base_uri.match(/test\/model\/bands.utf-8.xml/)) parser = LibXML::XML::Parser.file(file, :base_uri => "http://libxml.org") doc = parser.parse assert(doc.child.base_uri.match(/test\/model\/bands.utf-8.xml/)) end def test_io File.open(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) do |io| parser = LibXML::XML::Parser.io(io) assert_instance_of(LibXML::XML::Parser, parser) doc = parser.parse assert_instance_of(LibXML::XML::Document, doc) assert_instance_of(LibXML::XML::Parser::Context, parser.context) end end def test_io_gc # Test that the reader keeps a reference # to the io object file = File.open(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) parser = LibXML::XML::Parser.io(file) file = nil GC.start assert(parser.parse) end def test_nil_io error = assert_raises(TypeError) do LibXML::XML::Parser.io(nil) end assert_equal("Must pass in an IO object", error.to_s) end def test_string_io data = File.read(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) string_io = StringIO.new(data) parser = LibXML::XML::Parser.io(string_io) doc = parser.parse assert_instance_of(LibXML::XML::Document, doc) assert_instance_of(LibXML::XML::Parser::Context, parser.context) end def test_string_io_thread thread = Thread.new do data = File.read(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) string_io = StringIO.new(data) parser = LibXML::XML::Parser.io(string_io) doc = parser.parse assert_instance_of(LibXML::XML::Document, doc) assert_instance_of(LibXML::XML::Parser::Context, parser.context) end thread.join assert(true) puts 'Thread completed' end def test_string str = 'onetwo' parser = LibXML::XML::Parser.string(str) assert_instance_of(LibXML::XML::Parser, parser) doc = parser.parse assert_instance_of(LibXML::XML::Document, doc) assert_instance_of(LibXML::XML::Parser::Context, parser.context) end def test_nil_string error = assert_raises(TypeError) do LibXML::XML::Parser.string(nil) end assert_equal("wrong argument type nil (expected String)", error.to_s) end def test_string_options xml = <<-EOS ]> &foo; EOS LibXML::XML::default_substitute_entities = false # Parse normally parser = LibXML::XML::Parser.string(xml) doc = parser.parse assert_nil(doc.child.base_uri) # Cdata section should be cdata nodes node = doc.find_first('/test/cdata').child assert_equal(LibXML::XML::Node::CDATA_SECTION_NODE, node.node_type) # Entities should not be subtituted node = doc.find_first('/test/entity') assert_equal('&foo;', node.child.to_s) # Parse with options parser = LibXML::XML::Parser.string(xml, :base_uri => 'http://libxml.rubyforge.org', :options => LibXML::XML::Parser::Options::NOCDATA | LibXML::XML::Parser::Options::NOENT) doc = parser.parse assert_equal(doc.child.base_uri, 'http://libxml.rubyforge.org') # Cdata section should be text nodes node = doc.find_first('/test/cdata').child assert_equal(LibXML::XML::Node::TEXT_NODE, node.node_type) # Entities should be subtituted node = doc.find_first('/test/entity') assert_equal('bar', node.child.to_s) end def test_string_encoding # ISO_8859_1: # ö - f6 in hex, \366 in octal # ü - fc in hex, \374 in octal xml = <<-EOS m\366tley_cr\374e EOS # Parse as UTF_8 parser = LibXML::XML::Parser.string(xml, :encoding => LibXML::XML::Encoding::UTF_8) error = assert_raises(LibXML::XML::Error) do parser.parse end assert_equal("Fatal error: Input is not proper UTF-8, indicate encoding !\nBytes: 0xF6 0x74 0x6C 0x65 at :2.", error.to_s) # Parse as ISO_8859_1: parser = LibXML::XML::Parser.string(xml, :encoding => LibXML::XML::Encoding::ISO_8859_1) doc = parser.parse node = doc.find_first('//metal') assert_equal(Encoding::UTF_8, node.content.encoding) assert_equal("m\303\266tley_cr\303\274e", node.content) end def test_fd_gc # Test opening # of documents up to the file limit for the OS. # Ideally it should run until libxml emits a warning, # thereby knowing we've done a GC sweep. For the time being, # re-open the same doc `limit descriptors` times. # If we make it to the end, then we've succeeded, # otherwise an exception will be thrown. LibXML::XML::Error.set_handler {|error|} max_fd = if RUBY_PLATFORM.match(/mswin32|mswin64|mingw/i) 500 else Process.getrlimit(Process::RLIMIT_NOFILE)[0] + 1 end file = File.join(File.dirname(__FILE__), 'model/rubynet.xml') max_fd.times do LibXML::XML::Parser.file(file).parse end LibXML::XML::Error.reset_handler {|error|} end def test_open_many_files file = File.expand_path(File.join(File.dirname(__FILE__), 'model/atom.xml')) 1000.times do LibXML::XML::Parser.file(file).parse end end # ----- Errors ------ def test_error error = assert_raises(LibXML::XML::Error) do LibXML::XML::Parser.string('').parse end refute_nil(error) assert_kind_of(LibXML::XML::Error, error) assert_equal("Fatal error: Opening and ending tag mismatch: foo line 1 and foz at :1.", error.message) assert_equal(LibXML::XML::Error::PARSER, error.domain) assert_equal(LibXML::XML::Error::TAG_NAME_MISMATCH, error.code) assert_equal(LibXML::XML::Error::FATAL, error.level) assert_nil(error.file) assert_equal(1, error.line) assert_equal('foo', error.str1) assert_equal('foz', error.str2) assert_nil(error.str3) assert_equal(1, error.int1) assert_equal(20, error.int2) assert_nil(error.node) end def test_bad_xml parser = LibXML::XML::Parser.string('onetwo') error = assert_raises(LibXML::XML::Error) do refute_nil(parser.parse) end refute_nil(error) assert_kind_of(LibXML::XML::Error, error) assert_equal("Fatal error: Extra content at the end of the document at :1.", error.message) assert_equal(LibXML::XML::Error::PARSER, error.domain) assert_equal(LibXML::XML::Error::DOCUMENT_END, error.code) assert_equal(LibXML::XML::Error::FATAL, error.level) assert_nil(error.file) assert_equal(1, error.line) assert_nil(error.str1) assert_nil(error.str2) assert_nil(error.str3) assert_equal(0, error.int1) assert_equal(34, error.int2) assert_nil(error.node) end def test_errors_from_background_thread errors = [] background_errors = [] begin LibXML::XML::Error.set_handler do |error| errors << error end parser = LibXML::XML::Parser.string("") thread = Thread.new do LibXML::XML::Error.set_handler do |error| background_errors << error end parser.parse rescue nil end thread.join ensure LibXML::XML::Error.set_handler(&LibXML::XML::Error::QUIET_HANDLER) end assert_equal(errors.size, 0) assert_equal(background_errors.size, 1) end end libxml-ruby-3.2.1/test/test_xpath_expression.rb0000644000004100000410000000171413760147770022000 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class TestXPathExpression < Minitest::Test def setup xp = LibXML::XML::Parser.string('onetwo') @doc = xp.parse end def teardown @doc = nil end def test_nodes expr = LibXML::XML::XPath::Expression.compile('/ruby_array/fixnum') set = @doc.find(expr) assert_instance_of(LibXML::XML::XPath::Object, set) assert_equal(2, set.size) end def test_find_class expr = LibXML::XML::XPath::Expression.new('/ruby_array/fixnum') set = @doc.find(expr) assert_instance_of(LibXML::XML::XPath::Object, set) assert_equal(2, set.size) end def test_find_invalid error = assert_raises(TypeError) do @doc.find(999) end assert_equal('Argument should be an instance of a String or XPath::Expression', error.to_s) end end libxml-ruby-3.2.1/test/test_canonicalize.rb0000644000004100000410000001337413760147770021041 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class TestCanonicalize < Minitest::Test def path(file) File.join(File.dirname(__FILE__), file) end # (www.w3.org) 3.1 PIs, Comments, and Outside of Document Element # http://www.w3.org/TR/xml-c14n#Example-OutsideDoc def test_canonicalize_with_w3c_c14n_3_1 given_doc = LibXML::XML::Document.file(self.path('c14n/given/example-1.xml')) # With Comments expected_with_comments = IO.read(self.path('c14n/result/with-comments/example-1')) assert_equal(expected_with_comments, given_doc.canonicalize(:comments => true)) # Without Comments expected_without_comments = IO.read(self.path('c14n/result/without-comments/example-1')) assert_equal(expected_without_comments, given_doc.canonicalize) assert_equal(expected_without_comments, given_doc.canonicalize(:comments => false)) # Without Comments (XML_C14N_1_1) expected_1_1_without_comments = IO.read(self.path('c14n/result/1-1-without-comments/example-1')) mode = LibXML::XML::Document::XML_C14N_1_1 assert_equal(expected_1_1_without_comments, given_doc.canonicalize(:mode => mode)) end#test_canonicalize_with_w3c_c14n_3_1 # (www.w3.org) 3.2 Whitespace in Document Content # http://www.w3.org/TR/xml-c14n#Example-WhitespaceInContent def test_canonicalize_with_w3c_c14n_3_2 given_doc = LibXML::XML::Document.file(self.path('c14n/given/example-2.xml')) expected = IO.read(self.path('c14n/result/without-comments/example-2')) assert_equal(expected, given_doc.canonicalize) expected_1_1_without_comments = IO.read(self.path('c14n/result/1-1-without-comments/example-2')) mode = LibXML::XML::Document::XML_C14N_1_1 assert_equal(expected_1_1_without_comments, given_doc.canonicalize(:mode => mode)) end # (www.w3.org) 3.3 Start and End Tags # http://www.w3.org/TR/xml-c14n#Example-SETags # (2012-02-20) Test failing due to missing 'attr' in 'e9' node. # - Embedded DTD not parsed out of XML, therefore default attributes are # not applied to canonicalization. def test_canonicalize_with_w3c_c14n_3_3 given_doc = LibXML::XML::Document.file(self.path('c14n/given/example-3.xml')) expected = IO.read(self.path('c14n/result/without-comments/example-3')) assert_equal(expected, given_doc.canonicalize) expected_1_1_without_comments = IO.read(self.path('c14n/result/1-1-without-comments/example-3')) mode = LibXML::XML::Document::XML_C14N_1_1 assert_equal(expected_1_1_without_comments, given_doc.canonicalize(:mode => mode)) end # (www.w3.org) 3.4 Character Modifications and Character References # http://www.w3.org/TR/xml-c14n#Example-Chars def test_canonicalize_with_w3c_c14n_3_4 given_doc = LibXML::XML::Document.file(self.path('c14n/given/example-4.xml')) expected = IO.read(self.path('c14n/result/without-comments/example-4')) assert_equal(expected, given_doc.canonicalize) expected_1_1_without_comments = IO.read(self.path('c14n/result/1-1-without-comments/example-4')) mode = LibXML::XML::Document::XML_C14N_1_1 assert_equal(expected_1_1_without_comments, given_doc.canonicalize(:mode => mode)) end # (www.w3.org) 3.5 Entity References # http://www.w3.org/TR/xml-c14n#Example-Entities # (2012-02-20) Failing likely due to a logic error # - libxml2(c14n.c:1788) XML_ENTITY_REF_NODE is invalid node for parsing. def test_canonicalize_with_w3c_c14n_3_5 #given_doc = LibXML::XML::Document.file(self.path('c14n/given/example-5.xml')) # With Comments #expected_with_comments = IO.read(self.path('c14n/result/with-comments/example-5')) # TODO - CANNOT COMPLETE TEST unless libxml2 supports additional node types. #assert_equal(expected_with_comments, given_doc.canonicalize(:comments => true)) # Without Comments #expected_without_comments = IO.read(self.path('c14n/result/without-comments/example-5')) # TODO - CANNOT COMPLETE TEST unless libxml2 supports additional node types. #assert_equal(expected_without_comments, given_doc.canonicalize(:comments => false)) #expected_1_1_without_comments = IO.read(self.path('c14n/result/1-1-without-comments/example-5')) #mode = LibXML::XML::Document::XML_C14N_1_1 # TODO - CANNOT COMPLETE TEST unless libxml2 supports additional node types. #assert_equal(expected_1_1_without_comments, given_doc.canonicalize(:mode => mode)) end # (www.w3.org) 3.6 UTF-8 Encoding # http://www.w3.org/TR/xml-c14n#Example-UTF8 def test_canonicalize_with_w3c_c14n_3_6 given_doc = LibXML::XML::Document.file(self.path('c14n/given/example-6.xml')) expected = IO.read(self.path('c14n/result/without-comments/example-6'), :encoding => Encoding::UTF_8) assert_equal(expected, given_doc.canonicalize) expected_1_1_without_comments = IO.read(self.path('c14n/result/1-1-without-comments/example-6'), :encoding => Encoding::UTF_8) mode = LibXML::XML::Document::XML_C14N_1_1 assert_equal(expected_1_1_without_comments, given_doc.canonicalize(:mode => mode)) end # (www.w3.org) 3.7 Document Subsets # http://www.w3.org/TR/xml-c14n#Example-DocSubsets def test_canonicalize_with_w3c_c14n_3_7 # Non Canonicalized Document # given_doc = LibXML::XML::Document.file(self.path('c14n/given/example-7.xml')) #expected = IO.read(self.path('c14n/result/without-comments/example-7')) # e1_node = given_doc.find_first('ietf:e1', 'ietf:http://www.ietf.org') # Select current node, all child nodes, all attributes and namespace nodes #subdoc_nodes = e1_node.find("(.//.|.//@id|namespace::*)") # TODO - This fails because the namespace nodes aren't taken into account # assert_equal(expected, given_doc.canonicalize(:nodes => subdoc_nodes)) end end libxml-ruby-3.2.1/test/test_node_cdata.rb0000644000004100000410000000247413760147770020462 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class CDataCommentTest < Minitest::Test def setup xp = LibXML::XML::Parser.string('') @doc = xp.parse assert_instance_of(LibXML::XML::Document, @doc) @root = @doc.root end def test_node_type cnode = LibXML::XML::Node.new_cdata('test cdata') assert_equal(LibXML::XML::Node::CDATA_SECTION_NODE, cnode.node_type) end def test_add_cdata @root << LibXML::XML::Node.new_cdata('mycdata') assert_equal '', @root.to_s.gsub(/\n\s*/,'') end def test_add_cdata_2 @root << LibXML::XML::Node.new_cdata('mycdata') assert_equal 'cdata', @root.child.node_type_name end def test_add_cdata_3 @root << el = LibXML::XML::Node.new_cdata('mycdata') el << "_this_is_added" assert_equal '', @root.to_s.gsub(/\n\s*/,'') end def test_attributes cnode = LibXML::XML::Node.new_cdata('test cdata') assert_equal(0, cnode.attributes.length) end def test_set_cdata_attribute cnode = LibXML::XML::Node.new_cdata('test cdata') # Can't create attributes on non-element nodes assert_raises(ArgumentError) do cnode['attr'] = '123' end end end libxml-ruby-3.2.1/test/test_deprecated_require.rb0000644000004100000410000000056413760147770022233 0ustar www-datawww-data# encoding: UTF-8 require 'xml/libxml' class TestDeprecatedRequire < Minitest::Test def test_basic xp = LibXML::XML::Parser.string('onetwo') assert_instance_of(LibXML::XML::Parser, xp) @doc = xp.parse assert_instance_of(LibXML::XML::Document, @doc) end end libxml-ruby-3.2.1/test/test_node_comment.rb0000644000004100000410000000154413760147770021045 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class NodeCommentTest < Minitest::Test def setup xp = LibXML::XML::Parser.string('') @doc = xp.parse assert_instance_of(LibXML::XML::Document, @doc) @root = @doc.root end def test_libxml_node_add_comment_01 @root << LibXML::XML::Node.new_comment('mycomment') assert_equal '', @root.to_s.gsub(/\n\s*/,'') end def test_libxml_node_add_comment_02 @root << LibXML::XML::Node.new_comment('mycomment') assert_equal 'comment', @root.child.node_type_name end def test_libxml_node_add_comment_03 @root << el = LibXML::XML::Node.new_comment('mycomment') el << "_this_is_added" assert_equal '', @root.to_s.gsub(/\n\s*/,'') end end libxml-ruby-3.2.1/test/test_document.rb0000644000004100000410000001004213760147770020205 0ustar www-datawww-data# encoding: UTF-8 require_relative './test_helper' class TestDocument < Minitest::Test def setup xp = LibXML::XML::Parser.string('onetwo') assert_instance_of(LibXML::XML::Parser, xp) @doc = xp.parse assert_instance_of(LibXML::XML::Document, @doc) end def teardown @doc = nil end def test_klass assert_instance_of(LibXML::XML::Document, @doc) end def test_context context = @doc.context assert_instance_of(LibXML::XML::XPath::Context, context) end def test_find set = @doc.find('/ruby_array/fixnum') assert_instance_of(LibXML::XML::XPath::Object, set) assert_raises(NoMethodError) { set.xpath } end def test_compression if LibXML::XML.enabled_zlib? 0.upto(9) do |i| assert_equal(i, @doc.compression = i) assert_equal(i, @doc.compression) end 9.downto(0) do |i| assert_equal(i, @doc.compression = i) assert_equal(i, @doc.compression) end 10.upto(20) do |i| # assert_equal(9, @doc.compression = i) assert_equal(i, @doc.compression = i) # This works around a bug in Ruby 1.8 assert_equal(9, @doc.compression) end -1.downto(-10) do |i| # assert_equal(0, @doc.compression = i) assert_equal(i, @doc.compression = i) # FIXME This bug should get fixed ASAP assert_equal(0, @doc.compression) end end end def test_version assert_equal('1.0', @doc.version) doc = LibXML::XML::Document.new('6.9') assert_equal('6.9', doc.version) end def test_write_root @doc.root = LibXML::XML::Node.new('rubynet') assert_instance_of(LibXML::XML::Node, @doc.root) assert_instance_of(LibXML::XML::Document, @doc.root.doc) assert_equal("\n\n", @doc.to_s(:indent => false)) end def test_doc_node_type assert_equal(LibXML::XML::Node::DOCUMENT_NODE, LibXML::XML::Document.new.node_type) end def test_doc_node_type_name assert_equal('document_xml', LibXML::XML::Document.new.node_type_name) end def test_xhtml doc = LibXML::XML::Document.new assert(!doc.xhtml?) LibXML::XML::Dtd.new "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", nil, doc, true assert(doc.xhtml?) end def test_document_root doc1 = LibXML::XML::Document.string("") doc2 = LibXML::XML::Document.string("") error = assert_raises(LibXML::XML::Error) do doc1.root = doc2.root end assert_equal(" Nodes belong to different documents. You must first import the node by calling LibXML::XML::Document.import.", error.to_s) doc2.root << doc2.import(doc1.root) assert_equal('', doc1.root.to_s) assert_equal('', doc2.root.to_s(:indent => false)) assert(!doc1.root.equal?(doc2.root)) assert(doc1.root.doc != doc2.root.doc) end def test_import_node doc1 = LibXML::XML::Parser.string('').parse doc2 = LibXML::XML::Parser.string('').parse node = doc1.root.child error = assert_raises(LibXML::XML::Error) do doc2.root << node end assert_equal(" Nodes belong to different documents. You must first import the node by calling LibXML::XML::Document.import.", error.to_s) doc2.root << doc2.import(node) assert_equal("", doc2.root.to_s(:indent => false)) end def test_nonet xml_string = 'onetwo' xml = LibXML::XML::Document.string(xml_string, options: LibXML::XML::Parser::Options::NONET) schema_document = LibXML::XML::Document.file('d:/src/libxml-ruby/test/model/atom.xml', options: LibXML::XML::Parser::Options::NONET) end end libxml-ruby-3.2.1/test/test_helper.rb0000644000004100000410000000027513760147770017655 0ustar www-datawww-data# encoding: UTF-8 # To make testing/debugging easier, test within this source tree versus an installed gem require 'bundler/setup' require 'minitest/autorun' require 'libxml-ruby' libxml-ruby-3.2.1/MANIFEST0000644000004100000410000001057313760147770015166 0ustar www-datawww-data#!mast -x doc/libxml-ruby/rdoc -i .gitignore ext doc lib script test [A-Z]* ext/libxml/extconf.rb ext/libxml/libxml.c ext/libxml/ruby_libxml.h ext/libxml/ruby_xml.c ext/libxml/ruby_xml.h ext/libxml/ruby_xml_attr.c ext/libxml/ruby_xml_attr.h ext/libxml/ruby_xml_attr_decl.c ext/libxml/ruby_xml_attr_decl.h ext/libxml/ruby_xml_attributes.c ext/libxml/ruby_xml_attributes.h ext/libxml/ruby_xml_cbg.c ext/libxml/ruby_xml_document.c ext/libxml/ruby_xml_document.h ext/libxml/ruby_xml_dtd.c ext/libxml/ruby_xml_dtd.h ext/libxml/ruby_xml_encoding.c ext/libxml/ruby_xml_encoding.h ext/libxml/ruby_xml_error.c ext/libxml/ruby_xml_error.h ext/libxml/ruby_xml_html_parser.c ext/libxml/ruby_xml_html_parser.h ext/libxml/ruby_xml_html_parser_context.c ext/libxml/ruby_xml_html_parser_context.h ext/libxml/ruby_xml_html_parser_options.c ext/libxml/ruby_xml_html_parser_options.h ext/libxml/ruby_xml_input_cbg.c ext/libxml/ruby_xml_input_cbg.h ext/libxml/ruby_xml_io.c ext/libxml/ruby_xml_io.h ext/libxml/ruby_xml_namespace.c ext/libxml/ruby_xml_namespace.h ext/libxml/ruby_xml_namespaces.c ext/libxml/ruby_xml_namespaces.h ext/libxml/ruby_xml_node.c ext/libxml/ruby_xml_node.h ext/libxml/ruby_xml_parser.c ext/libxml/ruby_xml_parser.h ext/libxml/ruby_xml_parser_context.c ext/libxml/ruby_xml_parser_context.h ext/libxml/ruby_xml_parser_options.c ext/libxml/ruby_xml_parser_options.h ext/libxml/ruby_xml_reader.c ext/libxml/ruby_xml_reader.h ext/libxml/ruby_xml_relaxng.c ext/libxml/ruby_xml_relaxng.h ext/libxml/ruby_xml_sax2_handler.c ext/libxml/ruby_xml_sax2_handler.h ext/libxml/ruby_xml_sax_parser.c ext/libxml/ruby_xml_sax_parser.h ext/libxml/ruby_xml_schema.c ext/libxml/ruby_xml_schema.h ext/libxml/ruby_xml_version.h ext/libxml/ruby_xml_xinclude.c ext/libxml/ruby_xml_xinclude.h ext/libxml/ruby_xml_xpath.c ext/libxml/ruby_xml_xpath.h ext/libxml/ruby_xml_xpath_context.c ext/libxml/ruby_xml_xpath_context.h ext/libxml/ruby_xml_xpath_expression.c ext/libxml/ruby_xml_xpath_expression.h ext/libxml/ruby_xml_xpath_object.c ext/libxml/ruby_xml_xpath_object.h ext/libxml/ruby_xml_xpointer.c ext/libxml/ruby_xml_xpointer.h ext/mingw/Rakefile ext/mingw/build.rake ext/mingw/libiconv-2.dll ext/mingw/libxml2-2.dll ext/mingw/libxml_ruby.dll.a ext/mingw/libxml_ruby.so ext/vc/libxml_ruby.sln ext/vc/libxml_ruby_18/libxml_ruby.vcproj ext/vc/libxml_ruby_19/libxml_ruby_19.vcproj doc/.htaccess doc/.rsync-filter lib/libxml/attr.rb lib/libxml/attr_decl.rb lib/libxml/attributes.rb lib/libxml/document.rb lib/libxml/error.rb lib/libxml/hpricot.rb lib/libxml/html_parser.rb lib/libxml/namespace.rb lib/libxml/namespaces.rb lib/libxml/node.rb lib/libxml/ns.rb lib/libxml/parser.rb lib/libxml/properties.rb lib/libxml/reader.rb lib/libxml/sax_callbacks.rb lib/libxml/sax_parser.rb lib/libxml/tree.rb lib/libxml/xpath_object.rb lib/libxml.rb lib/xml/libxml.rb lib/xml.rb script/benchmark/depixelate script/benchmark/hamlet.xml script/benchmark/parsecount script/benchmark/sock_entries.xml script/benchmark/throughput script/test test/etc_doc_to_s.rb test/ets_doc_file.rb test/ets_doc_to_s.rb test/ets_gpx.rb test/ets_node_gc.rb test/ets_test.xml test/ets_tsr.rb test/model/atom.xml test/model/bands.xml test/model/books.xml test/model/merge_bug_data.xml test/model/ruby-lang.html test/model/rubynet.xml test/model/rubynet_project test/model/shiporder.rnc test/model/shiporder.rng test/model/shiporder.xml test/model/shiporder.xsd test/model/soap.xml test/model/xinclude.xml test/test_attr.rb test/test_attr_decl.rb test/test_attributes.rb test/test_deprecated_require.rb test/test_document.rb test/test_document_write.rb test/test_dtd.rb test/test_error.rb test/test_html_parser.rb test/test_namespace.rb test/test_namespaces.rb test/test_node.rb test/test_node_cdata.rb test/test_node_comment.rb test/test_node_copy.rb test/test_node_edit.rb test/test_node_pi.rb test/test_node_text.rb test/test_node_write.rb test/test_node_xlink.rb test/test_parser.rb test/test_parser_context.rb test/test_properties.rb test/test_reader.rb test/test_relaxng.rb test/test_sax_parser.rb test/test_schema.rb test/test_traversal.rb test/test_xinclude.rb test/test_xml.rb test/test_xpath.rb test/test_xpath_context.rb test/test_xpath_expression.rb test/test_xpointer.rb test/test_suite.rb Rakefile HISTORY.rdoc PROFILE TODO LICENSE README.rdoc VERSION libxml-ruby-3.2.1/script/0000755000004100000410000000000013760147770015333 5ustar www-datawww-datalibxml-ruby-3.2.1/script/test0000644000004100000410000000017113760147770016234 0ustar www-datawww-data#!/usr/bin/env ruby %w{test lib ext/libxml}.each{ |path| $LOAD_PATH.unshift(path) } load './test/test_suite.rb' libxml-ruby-3.2.1/script/benchmark/0000755000004100000410000000000013760147770017265 5ustar www-datawww-datalibxml-ruby-3.2.1/script/benchmark/parsecount0000644000004100000410000001635113760147770021401 0ustar www-datawww-data#!/usr/bin/env ruby # # Each test has an XML Parser open a 98k XML document and count one type of leaf # element (466 entries). This is repeated a total of 100 times, twice for each Parser. # Summary measurements are from the second test. # # Tests run on a MacBook Pro, Mac OS X 10.5.5, 4GB memory, 2.5 GHz Intel Core 2 Duo. # # Library versions: # hpricot 0.6.164 # libxml: 0.9.2 # # All benchmarks were run twice in sequence and the measurements presented here are from # the second run. Java automatically optimizes JRuby code which is run many times and the # speedup from the first to the second test is from 40 to 75%. There is no essential # difference in the speed of the C version of Ruby between the first test and the second. # # Summary: # # 100 times: Open 98k XML document and count one type of leaf element (466 entries) # # JRuby (Java 1.6.0_03-p3-Soylatte using server mode): jdom_document_builder 0.360 # MRI: libxml v0.9.2 0.383 # JRuby (Java 1.6.0_07): jdom_document_builder 0.401 # JRuby (Java 1.5.0_16): jdom_document_builder 0.428 # JRuby (Java 1.6.0_03-p3-Soylatte using server mode): hpricot 1.977 # JRuby (Java 1.5.0_16): hpricot 2.027 # JRuby (Java 1.6.0_07): hpricot 2.094 # MRI: hpricot 2.140 # JRuby (Java 1.6.0_03-p3-Soylatte using server mode): rexml 5.488 # JRuby (Java 1.5.0_16): rexml 5.569 # JRuby (Java 1.5.0_16): rexml 5.578 # MRI: rexml 8.606 # # Ruby version: MRI 1.8.6 (2008-03-03 rev 114), platform: universal-darwin9.0 # -------------------------------------------------------------------------------- # user system total real # rexml 8.170000 0.100000 8.270000 ( 8.606676) # hpricot 1.990000 0.040000 2.030000 ( 2.140865) # libxml 0.350000 0.020000 0.370000 ( 0.383475) # # JRuby 1.1.5 (svn r8078) on Java 1.5.0_16 # -------------------------------------------------------------------------------- # user system total real # rexml 5.578000 0.000000 5.578000 ( 5.578371) # hpricot 2.028000 0.000000 2.028000 ( 2.027348) # jdom_document_builder 0.429000 0.000000 0.429000 ( 0.428713) # # JRuby 1.1.5 (svn r8078) on Java 1.6.0_07 # -------------------------------------------------------------------------------- # user system total real # rexml 5.569000 0.000000 5.569000 ( 5.569135) # hpricot 2.094000 0.000000 2.094000 ( 2.093635) # jdom_document_builder 0.401000 0.000000 0.401000 ( 0.401115) # # JRuby 1.1.5 (svn r8078) on Java 1.6.0_07 using server mode (-J-server) # -------------------------------------------------------------------------------- # user system total real # rexml 5.489000 0.000000 5.489000 ( 5.488560) # hpricot 1.977000 0.000000 1.977000 ( 1.976845) # jdom_document_builder 0.377000 0.000000 0.377000 ( 0.377808) # # JRuby 1.1.5 (svn r8078) on Java 1.6.0_03-p3 (Soylatte) using server mode (-J-server) # -------------------------------------------------------------------------------- # user system total real # rexml 5.596000 0.000000 5.596000 ( 5.596212) # hpricot 1.937000 0.000000 1.937000 ( 1.937312) # jdom_document_builder 0.360000 0.000000 0.360000 ( 0.360068) require 'rubygems' require 'benchmark' require "rexml/document" require 'hpricot' if RUBY_PLATFORM =~ /java/ include Java import javax.xml.parsers.DocumentBuilder import javax.xml.parsers.DocumentBuilderFactory @dbf = DocumentBuilderFactory.new_instance @ruby_info = "Ruby version: JRuby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE} rev #{RUBY_PATCHLEVEL}) [i386-jruby#{JRUBY_VERSION}]" @ruby_info << ", platform: Java, version #{java.lang.System.getProperty('java.version')}" else @ruby_info = "Ruby version: MRI #{RUBY_VERSION} (#{RUBY_RELEASE_DATE} rev #{RUBY_PATCHLEVEL})" @ruby_info << ", platform: #{RUBY_PLATFORM}" gem 'nokogiri', '>= 1.0.6' require 'nokogiri' gem 'libxml-ruby', '>= 0.9.2' require 'libxml' @xml_parser = LibXML::XML::Parser.new end file = File.expand_path(File.join(File.dirname(__FILE__), "sock_entries.xml")) @bundle_with_466_sock_entries = File.read(file) def rexml_count_socks doc = REXML::Document.new(@bundle_with_466_sock_entries).root socks = doc.elements.to_a('./sockEntries').length end unless RUBY_PLATFORM =~ /java/ def nokogiri_count_socks #doc = Nokogiri(@bundle_with_466_sock_entries) #socks = doc.search('//sockEntries').length end def libxml_count_socks @xml_parser = LibXML::XML::Parser.new @xml_parser.string = @bundle_with_466_sock_entries doc = @xml_parser.parse socks = doc.find('//sockEntries').length end end def hpricot_count_socks doc = Hpricot.XML(@bundle_with_466_sock_entries) socks = doc.search("//sockEntries").length end if RUBY_PLATFORM =~ /java/ def jdom_document_builder_count_socks file = File.expand_path(File.join(File.dirname(__FILE__), "sock_entries.xml")) doc = @dbf.new_document_builder.parse(file).get_document_element socks = doc.getElementsByTagName("sockEntries") socks.get_length end end n = 100 test_iterations = ARGV.first.to_i test_iterations = 1 unless test_iterations > 1 puts puts @ruby_info puts puts "#{n} times: Open 98k XML document and count one type of leaf element (466 entries)" puts print "running benchmark " if test_iterations == 1 puts "once.\n\n" else puts "#{test_iterations} times.\n\n" end test_iterations.times do Benchmark.bmbm do |x| x.report("rexml") { n.times {rexml_count_socks} } x.report("hpricot") { n.times {hpricot_count_socks} } x.report("jdom_document_builder") { n.times {jdom_document_builder_count_socks} } if RUBY_PLATFORM =~ /java/ #x.report("nokogiri") { n.times {nokogiri_count_socks} } unless RUBY_PLATFORM =~ /java/ x.report("libxml") { n.times {libxml_count_socks} } unless RUBY_PLATFORM =~ /java/ end puts end # # jrexml doesn't appear to have any speedup in this test # # if RUBY_PLATFORM =~ /java/ # require 'jrexml' # def rexml_with_jrexml_count_socks # doc = REXML::Document.new(@bundle_with_466_sock_entries).root # socks = doc.elements.to_a('./sockEntries').length # end # # puts "\nNow add in JREXML to see if it speeds up rexml\n" # Benchmark.bmbm do |x| # x.report("rexml+jrexml") { n.times {rexml_with_jrexml_count_socks} } # end # puts # end libxml-ruby-3.2.1/script/benchmark/depixelate0000644000004100000410000005711113760147770021341 0ustar www-datawww-data#!/usr/bin/env ruby require 'rubygems' require 'benchmark' require 'hpricot' require 'rexml/document' require 'xml' # Taken from http://depixelate.com/2008/4/23/ruby-xml-parsing-benchmarks XML_STRING = DATA.read class Parse def self.libxml doc = XML::Parser.string(XML_STRING).parse ary = [] doc.find('/*/*/*').each do |node| case node.name when 'ItemQueryRs' node.each_element do |child| ary << child.find_first('./ListID') end end end ary end def self.rexml doc = REXML::Document.new(XML_STRING) ary = [] REXML::XPath.each(doc, '/*/*/*') do |node| case node.name when 'ItemQueryRs' node.elements.each do |element| ary << rexml_fetch(element, 'ListID') end end end ary end def self.hpricot doc = Hpricot.XML(XML_STRING) ary = [] response_element = doc.search('/*/*/*').each do |node| next unless node.elem? case node.name when 'ItemQueryRs' node.containers.each do |element| ary << hpricot_fetch(element/'ListID') end end end ary end # rexml helper def self.rexml_fetch(node, name) e = REXML::XPath.first(node, name) e ? e.text : nil end # hpricot helper def self.hpricot_fetch(path) return nil if path.nil? || path.empty? path = path.first if path.is_a?(Array) path.innerHTML end end TIMES = 10 Benchmark.bmbm do |x| x.report('libxml') { TIMES.times { Parse.libxml } } x.report('Hpricot') { TIMES.times { Parse.hpricot } } x.report('REXML') { TIMES.times { Parse.rexml } } end __END__ 240000-1071531214 2003-12-15T15:33:34-08:00 2003-12-15T15:34:51-08:00 1071531291 Delivery Delivery true 0 20000-999021789 Non Delivery Service Fee (free for orders over $100) 15.00 610001-1071531179 Service 10000-934380927 1999-08-11T07:15:27-08:00 1999-08-11T07:15:27-08:00 934380927 Design Design true 0 20000-999021789 Non Custom Landscape Design 55.00 150000-934380913 Landscaping Services:Design Services 20000-934380927 1999-08-11T07:15:27-08:00 1999-08-11T08:59:12-08:00 934387152 Gardening Gardening true 0 20000-999021789 Non Weekly gardening services 0.00 1F0000-934380913 Landscaping Services:Labor:Installation 30000-934380927 1999-08-11T07:15:27-08:00 1999-08-11T07:15:27-08:00 934380927 Installation Installation true 0 20000-999021789 Non Installation of landscape design 35.00 1F0000-934380913 Landscaping Services:Labor:Installation 40000-934380927 1999-08-11T07:15:27-08:00 1999-08-11T07:15:27-08:00 934380927 Pest Control Pest Control true 0 20000-999021789 Non Pest control services 0.00 200000-934380913 Landscaping Services:Labor:Maintenance & Repairs 2E0000-1071514896 2003-12-15T11:01:36-08:00 2003-12-15T14:42:51-08:00 1071528171 Tree Removal Tree Removal true 0 20000-999021789 Non Tree Removal Service 0.00 610001-1071531179 Service 50000-934380927 1999-08-11T07:15:27-08:00 1999-08-11T07:15:27-08:00 934380927 Trimming Trimming true 0 20000-999021789 Non Tree and shrub trimming 35.00 200000-934380913 Landscaping Services:Labor:Maintenance & Repairs B0000-934380927 1999-08-11T07:15:27-08:00 1999-08-11T07:15:27-08:00 934380927 Concrete Concrete true 0 10000-999021789 Tax Concrete for fountain installation 0.00 1B0000-934380913 Landscaping Services:Job Materials:Fountains & Garden Lighting C0000-934380927 1999-08-11T07:15:27-08:00 1999-08-11T07:15:27-08:00 934380927 Deck Lumber Deck Lumber true 0 10000-999021789 Tax Deck Lumber 0.00 1A0000-934380913 Landscaping Services:Job Materials:Decks & Patios 210000-1071530240 2003-12-15T15:17:20-08:00 2003-12-15T15:17:20-08:00 1071530240 Fertilizer Fertilizer true 0 10000-999021789 Tax Parent Item - Do Not Use 0.00 600001-1071530232 Retail Sales 250000-1071523682 2003-12-15T13:28:02-08:00 2003-12-15T13:44:20-08:00 1071524660 Irrigation Hose Irrigation Hose true 0 10000-999021789 Tax Parent Item Vinyl Irrigation Line- Do Not Purchase or Sell 0.00 690001-1071523679 Landscaping Services:Job Materials:Misc Materials Vinyl Irrigation LineParent Item - Do Not Purchase or Sell 0.00 240000-934380913 Cost of Goods Sold 60000-934380912 Inventory Asset -1 0 0.00 0 0 270000-1071524193 2003-12-15T13:36:33-08:00 2003-12-15T13:38:13-08:00 1071524293 1/2" Line Irrigation Hose:1/2" Line true 250000-1071523682 Irrigation Hose 1 10000-999021789 Tax 1/2" Vinyl Irrigation Line 0.15 690001-1071523679 Landscaping Services:Job Materials:Misc Materials 1/2" Vinyl Irrigation Line 0.12 240000-934380913 Cost of Goods Sold 60000-934380912 Inventory Asset 1500 1783 0.12 0 0 260000-1071523858 2003-12-15T13:30:58-08:00 2003-12-15T13:37:52-08:00 1071524272 1/4" Line Irrigation Hose:1/4" Line true 250000-1071523682 Irrigation Hose 1 10000-999021789 Tax 1/4" Vinyl Irrigation Line 0.10 690001-1071523679 Landscaping Services:Job Materials:Misc Materials 1/4" Vinyl Irrigation Line 0.07 240000-934380913 Cost of Goods Sold 60000-934380912 Inventory Asset 500 1235 0.07 0 0 280000-1071524260 2003-12-15T13:37:40-08:00 2003-12-15T13:37:40-08:00 1071524260 3/4" Line Irrigation Hose:3/4" Line true 250000-1071523682 Irrigation Hose 1 10000-999021789 Tax 3/4" Vinyl Irrigation Line 0.27 690001-1071523679 Landscaping Services:Job Materials:Misc Materials 3/4" Vinyl Irrigation Line 0.18 240000-934380913 Cost of Goods Sold 60000-934380912 Inventory Asset 1500 2670 0.18 0 0 60000-934380927 1999-08-11T07:15:27-08:00 1999-08-11T07:15:27-08:00 934380927 Lighting Lighting true 0 10000-999021789 Tax Garden Lighting 0.00 1B0000-934380913 Landscaping Services:Job Materials:Fountains & Garden Lighting Garden Lighting 0.00 240000-934380913 Cost of Goods Sold 60000-934380912 Inventory Asset 94 14.80 28 0 70000-934380927 1999-08-11T07:15:27-08:00 1999-08-11T07:15:27-08:00 934380927 Pump Pump true 0 10000-999021789 Tax Fountain pump 75.00 1B0000-934380913 Landscaping Services:Job Materials:Fountains & Garden Lighting Fountain pump #198-30 56.00 240000-934380913 Cost of Goods Sold 60000-934380912 Inventory Asset 48 53.93 0 0 80000-934380927 1999-08-11T07:15:27-08:00 1999-08-11T07:15:27-08:00 934380927 Soil Soil true 0 10000-999021789 Tax Soil, 2 cubic ft bag 6.75 1C0000-934380913 Landscaping Services:Job Materials:Plants and Sod Soil, 2 cubic ft bag 5.30 240000-934380913 Cost of Goods Sold 10000-934380927 Middlefield Nursery 60000-934380912 Inventory Asset 25 0 5.30 6 10 90000-934380927 1999-08-11T07:15:27-08:00 1999-08-11T07:15:27-08:00 934380927 Sprinkler Hds Sprinkler Hds true 0 10000-999021789 Tax Sprinkler heads 0.00 1D0000-934380913 Landscaping Services:Job Materials:Sprinklers & Drip systems Sprinkler head #BLS9081-09 0.00 240000-934380913 Cost of Goods Sold 60000-934380912 Inventory Asset 69 6.38 36 0 A0000-934380927 1999-08-11T07:15:27-08:00 1999-08-11T07:15:27-08:00 934380927 Sprkl pipes Sprkl pipes true 0 10000-999021789 Tax Plastic sprinkler piping 2.75 1D0000-934380913 Landscaping Services:Job Materials:Sprinklers & Drip systems Plastic sprinkler piping #1098-20 2.10 240000-934380913 Cost of Goods Sold 60000-934380912 Inventory Asset 250 826 2.10 115 0 libxml-ruby-3.2.1/script/benchmark/hamlet.xml0000644000004100000410000106366413760147770021301 0ustar www-datawww-data The Tragedy of Hamlet, Prince of Denmark

ASCII text placed in the public domain by Moby Lexical Tools, 1992.

SGML markup by Jon Bosak, 1992-1994.

XML version by Jon Bosak, 1996-1999.

The XML markup in this version is Copyright © 1999 Jon Bosak. This work may freely be distributed on condition that it not be modified or altered in any way.

Dramatis Personae CLAUDIUS, king of Denmark. HAMLET, son to the late, and nephew to the present king. POLONIUS, lord chamberlain. HORATIO, friend to Hamlet. LAERTES, son to Polonius. LUCIANUS, nephew to the king. VOLTIMAND CORNELIUS ROSENCRANTZ GUILDENSTERN OSRIC courtiers. A Gentleman A Priest. MARCELLUS BERNARDO officers. FRANCISCO, a soldier. REYNALDO, servant to Polonius. Players. Two Clowns, grave-diggers. FORTINBRAS, prince of Norway. A Captain. English Ambassadors. GERTRUDE, queen of Denmark, and mother to Hamlet. OPHELIA, daughter to Polonius. Lords, Ladies, Officers, Soldiers, Sailors, Messengers, and other Attendants. Ghost of Hamlet's Father. SCENE Denmark. HAMLET ACT I SCENE I. Elsinore. A platform before the castle. FRANCISCO at his post. Enter to him BERNARDO BERNARDO Who's there? FRANCISCO Nay, answer me: stand, and unfold yourself. BERNARDO Long live the king! FRANCISCO Bernardo? BERNARDO He. FRANCISCO You come most carefully upon your hour. BERNARDO 'Tis now struck twelve; get thee to bed, Francisco. FRANCISCO For this relief much thanks: 'tis bitter cold, And I am sick at heart. BERNARDO Have you had quiet guard? FRANCISCO Not a mouse stirring. BERNARDO Well, good night. If you do meet Horatio and Marcellus, The rivals of my watch, bid them make haste. FRANCISCO I think I hear them. Stand, ho! Who's there? Enter HORATIO and MARCELLUS HORATIO Friends to this ground. MARCELLUS And liegemen to the Dane. FRANCISCO Give you good night. MARCELLUS O, farewell, honest soldier: Who hath relieved you? FRANCISCO Bernardo has my place. Give you good night. Exit MARCELLUS Holla! Bernardo! BERNARDO Say, What, is Horatio there? HORATIO A piece of him. BERNARDO Welcome, Horatio: welcome, good Marcellus. MARCELLUS What, has this thing appear'd again to-night? BERNARDO I have seen nothing. MARCELLUS Horatio says 'tis but our fantasy, And will not let belief take hold of him Touching this dreaded sight, twice seen of us: Therefore I have entreated him along With us to watch the minutes of this night; That if again this apparition come, He may approve our eyes and speak to it. HORATIO Tush, tush, 'twill not appear. BERNARDO Sit down awhile; And let us once again assail your ears, That are so fortified against our story What we have two nights seen. HORATIO Well, sit we down, And let us hear Bernardo speak of this. BERNARDO Last night of all, When yond same star that's westward from the pole Had made his course to illume that part of heaven Where now it burns, Marcellus and myself, The bell then beating one,-- Enter Ghost MARCELLUS Peace, break thee off; look, where it comes again! BERNARDO In the same figure, like the king that's dead. MARCELLUS Thou art a scholar; speak to it, Horatio. BERNARDO Looks it not like the king? mark it, Horatio. HORATIO Most like: it harrows me with fear and wonder. BERNARDO It would be spoke to. MARCELLUS Question it, Horatio. HORATIO What art thou that usurp'st this time of night, Together with that fair and warlike form In which the majesty of buried Denmark Did sometimes march? by heaven I charge thee, speak! MARCELLUS It is offended. BERNARDO See, it stalks away! HORATIO Stay! speak, speak! I charge thee, speak! Exit Ghost MARCELLUS 'Tis gone, and will not answer. BERNARDO How now, Horatio! you tremble and look pale: Is not this something more than fantasy? What think you on't? HORATIO Before my God, I might not this believe Without the sensible and true avouch Of mine own eyes. MARCELLUS Is it not like the king? HORATIO As thou art to thyself: Such was the very armour he had on When he the ambitious Norway combated; So frown'd he once, when, in an angry parle, He smote the sledded Polacks on the ice. 'Tis strange. MARCELLUS Thus twice before, and jump at this dead hour, With martial stalk hath he gone by our watch. HORATIO In what particular thought to work I know not; But in the gross and scope of my opinion, This bodes some strange eruption to our state. MARCELLUS Good now, sit down, and tell me, he that knows, Why this same strict and most observant watch So nightly toils the subject of the land, And why such daily cast of brazen cannon, And foreign mart for implements of war; Why such impress of shipwrights, whose sore task Does not divide the Sunday from the week; What might be toward, that this sweaty haste Doth make the night joint-labourer with the day: Who is't that can inform me? HORATIO That can I; At least, the whisper goes so. Our last king, Whose image even but now appear'd to us, Was, as you know, by Fortinbras of Norway, Thereto prick'd on by a most emulate pride, Dared to the combat; in which our valiant Hamlet-- For so this side of our known world esteem'd him-- Did slay this Fortinbras; who by a seal'd compact, Well ratified by law and heraldry, Did forfeit, with his life, all those his lands Which he stood seized of, to the conqueror: Against the which, a moiety competent Was gaged by our king; which had return'd To the inheritance of Fortinbras, Had he been vanquisher; as, by the same covenant, And carriage of the article design'd, His fell to Hamlet. Now, sir, young Fortinbras, Of unimproved mettle hot and full, Hath in the skirts of Norway here and there Shark'd up a list of lawless resolutes, For food and diet, to some enterprise That hath a stomach in't; which is no other-- As it doth well appear unto our state-- But to recover of us, by strong hand And terms compulsatory, those foresaid lands So by his father lost: and this, I take it, Is the main motive of our preparations, The source of this our watch and the chief head Of this post-haste and romage in the land. BERNARDO I think it be no other but e'en so: Well may it sort that this portentous figure Comes armed through our watch; so like the king That was and is the question of these wars. HORATIO A mote it is to trouble the mind's eye. In the most high and palmy state of Rome, A little ere the mightiest Julius fell, The graves stood tenantless and the sheeted dead Did squeak and gibber in the Roman streets: As stars with trains of fire and dews of blood, Disasters in the sun; and the moist star Upon whose influence Neptune's empire stands Was sick almost to doomsday with eclipse: And even the like precurse of fierce events, As harbingers preceding still the fates And prologue to the omen coming on, Have heaven and earth together demonstrated Unto our climatures and countrymen.-- But soft, behold! lo, where it comes again! Re-enter Ghost I'll cross it, though it blast me. Stay, illusion! If thou hast any sound, or use of voice, Speak to me: If there be any good thing to be done, That may to thee do ease and grace to me, Speak to me: Cock crows If thou art privy to thy country's fate, Which, happily, foreknowing may avoid, O, speak! Or if thou hast uphoarded in thy life Extorted treasure in the womb of earth, For which, they say, you spirits oft walk in death, Speak of it: stay, and speak! Stop it, Marcellus. MARCELLUS Shall I strike at it with my partisan? HORATIO Do, if it will not stand. BERNARDO 'Tis here! HORATIO 'Tis here! MARCELLUS 'Tis gone! Exit Ghost We do it wrong, being so majestical, To offer it the show of violence; For it is, as the air, invulnerable, And our vain blows malicious mockery. BERNARDO It was about to speak, when the cock crew. HORATIO And then it started like a guilty thing Upon a fearful summons. I have heard, The cock, that is the trumpet to the morn, Doth with his lofty and shrill-sounding throat Awake the god of day; and, at his warning, Whether in sea or fire, in earth or air, The extravagant and erring spirit hies To his confine: and of the truth herein This present object made probation. MARCELLUS It faded on the crowing of the cock. Some say that ever 'gainst that season comes Wherein our Saviour's birth is celebrated, The bird of dawning singeth all night long: And then, they say, no spirit dares stir abroad; The nights are wholesome; then no planets strike, No fairy takes, nor witch hath power to charm, So hallow'd and so gracious is the time. HORATIO So have I heard and do in part believe it. But, look, the morn, in russet mantle clad, Walks o'er the dew of yon high eastward hill: Break we our watch up; and by my advice, Let us impart what we have seen to-night Unto young Hamlet; for, upon my life, This spirit, dumb to us, will speak to him. Do you consent we shall acquaint him with it, As needful in our loves, fitting our duty? MARCELLUS Let's do't, I pray; and I this morning know Where we shall find him most conveniently. Exeunt SCENE II. A room of state in the castle. Enter KING CLAUDIUS, QUEEN GERTRUDE, HAMLET, POLONIUS, LAERTES, VOLTIMAND, CORNELIUS, Lords, and Attendants KING CLAUDIUS Though yet of Hamlet our dear brother's death The memory be green, and that it us befitted To bear our hearts in grief and our whole kingdom To be contracted in one brow of woe, Yet so far hath discretion fought with nature That we with wisest sorrow think on him, Together with remembrance of ourselves. Therefore our sometime sister, now our queen, The imperial jointress to this warlike state, Have we, as 'twere with a defeated joy,-- With an auspicious and a dropping eye, With mirth in funeral and with dirge in marriage, In equal scale weighing delight and dole,-- Taken to wife: nor have we herein barr'd Your better wisdoms, which have freely gone With this affair along. For all, our thanks. Now follows, that you know, young Fortinbras, Holding a weak supposal of our worth, Or thinking by our late dear brother's death Our state to be disjoint and out of frame, Colleagued with the dream of his advantage, He hath not fail'd to pester us with message, Importing the surrender of those lands Lost by his father, with all bonds of law, To our most valiant brother. So much for him. Now for ourself and for this time of meeting: Thus much the business is: we have here writ To Norway, uncle of young Fortinbras,-- Who, impotent and bed-rid, scarcely hears Of this his nephew's purpose,--to suppress His further gait herein; in that the levies, The lists and full proportions, are all made Out of his subject: and we here dispatch You, good Cornelius, and you, Voltimand, For bearers of this greeting to old Norway; Giving to you no further personal power To business with the king, more than the scope Of these delated articles allow. Farewell, and let your haste commend your duty. CORNELIUS VOLTIMAND In that and all things will we show our duty. KING CLAUDIUS We doubt it nothing: heartily farewell. Exeunt VOLTIMAND and CORNELIUS And now, Laertes, what's the news with you? You told us of some suit; what is't, Laertes? You cannot speak of reason to the Dane, And loose your voice: what wouldst thou beg, Laertes, That shall not be my offer, not thy asking? The head is not more native to the heart, The hand more instrumental to the mouth, Than is the throne of Denmark to thy father. What wouldst thou have, Laertes? LAERTES My dread lord, Your leave and favour to return to France; From whence though willingly I came to Denmark, To show my duty in your coronation, Yet now, I must confess, that duty done, My thoughts and wishes bend again toward France And bow them to your gracious leave and pardon. KING CLAUDIUS Have you your father's leave? What says Polonius? LORD POLONIUS He hath, my lord, wrung from me my slow leave By laboursome petition, and at last Upon his will I seal'd my hard consent: I do beseech you, give him leave to go. KING CLAUDIUS Take thy fair hour, Laertes; time be thine, And thy best graces spend it at thy will! But now, my cousin Hamlet, and my son,-- HAMLET Aside A little more than kin, and less than kind. KING CLAUDIUS How is it that the clouds still hang on you? HAMLET Not so, my lord; I am too much i' the sun. QUEEN GERTRUDE Good Hamlet, cast thy nighted colour off, And let thine eye look like a friend on Denmark. Do not for ever with thy vailed lids Seek for thy noble father in the dust: Thou know'st 'tis common; all that lives must die, Passing through nature to eternity. HAMLET Ay, madam, it is common. QUEEN GERTRUDE If it be, Why seems it so particular with thee? HAMLET Seems, madam! nay it is; I know not 'seems.' 'Tis not alone my inky cloak, good mother, Nor customary suits of solemn black, Nor windy suspiration of forced breath, No, nor the fruitful river in the eye, Nor the dejected 'havior of the visage, Together with all forms, moods, shapes of grief, That can denote me truly: these indeed seem, For they are actions that a man might play: But I have that within which passeth show; These but the trappings and the suits of woe. KING CLAUDIUS 'Tis sweet and commendable in your nature, Hamlet, To give these mourning duties to your father: But, you must know, your father lost a father; That father lost, lost his, and the survivor bound In filial obligation for some term To do obsequious sorrow: but to persever In obstinate condolement is a course Of impious stubbornness; 'tis unmanly grief; It shows a will most incorrect to heaven, A heart unfortified, a mind impatient, An understanding simple and unschool'd: For what we know must be and is as common As any the most vulgar thing to sense, Why should we in our peevish opposition Take it to heart? Fie! 'tis a fault to heaven, A fault against the dead, a fault to nature, To reason most absurd: whose common theme Is death of fathers, and who still hath cried, From the first corse till he that died to-day, 'This must be so.' We pray you, throw to earth This unprevailing woe, and think of us As of a father: for let the world take note, You are the most immediate to our throne; And with no less nobility of love Than that which dearest father bears his son, Do I impart toward you. For your intent In going back to school in Wittenberg, It is most retrograde to our desire: And we beseech you, bend you to remain Here, in the cheer and comfort of our eye, Our chiefest courtier, cousin, and our son. QUEEN GERTRUDE Let not thy mother lose her prayers, Hamlet: I pray thee, stay with us; go not to Wittenberg. HAMLET I shall in all my best obey you, madam. KING CLAUDIUS Why, 'tis a loving and a fair reply: Be as ourself in Denmark. Madam, come; This gentle and unforced accord of Hamlet Sits smiling to my heart: in grace whereof, No jocund health that Denmark drinks to-day, But the great cannon to the clouds shall tell, And the king's rouse the heavens all bruit again, Re-speaking earthly thunder. Come away. Exeunt all but HAMLET HAMLET O, that this too too solid flesh would melt Thaw and resolve itself into a dew! Or that the Everlasting had not fix'd His canon 'gainst self-slaughter! O God! God! How weary, stale, flat and unprofitable, Seem to me all the uses of this world! Fie on't! ah fie! 'tis an unweeded garden, That grows to seed; things rank and gross in nature Possess it merely. That it should come to this! But two months dead: nay, not so much, not two: So excellent a king; that was, to this, Hyperion to a satyr; so loving to my mother That he might not beteem the winds of heaven Visit her face too roughly. Heaven and earth! Must I remember? why, she would hang on him, As if increase of appetite had grown By what it fed on: and yet, within a month-- Let me not think on't--Frailty, thy name is woman!-- A little month, or ere those shoes were old With which she follow'd my poor father's body, Like Niobe, all tears:--why she, even she-- O, God! a beast, that wants discourse of reason, Would have mourn'd longer--married with my uncle, My father's brother, but no more like my father Than I to Hercules: within a month: Ere yet the salt of most unrighteous tears Had left the flushing in her galled eyes, She married. O, most wicked speed, to post With such dexterity to incestuous sheets! It is not nor it cannot come to good: But break, my heart; for I must hold my tongue. Enter HORATIO, MARCELLUS, and BERNARDO HORATIO Hail to your lordship! HAMLET I am glad to see you well: Horatio,--or I do forget myself. HORATIO The same, my lord, and your poor servant ever. HAMLET Sir, my good friend; I'll change that name with you: And what make you from Wittenberg, Horatio? Marcellus? MARCELLUS My good lord-- HAMLET I am very glad to see you. Good even, sir. But what, in faith, make you from Wittenberg? HORATIO A truant disposition, good my lord. HAMLET I would not hear your enemy say so, Nor shall you do mine ear that violence, To make it truster of your own report Against yourself: I know you are no truant. But what is your affair in Elsinore? We'll teach you to drink deep ere you depart. HORATIO My lord, I came to see your father's funeral. HAMLET I pray thee, do not mock me, fellow-student; I think it was to see my mother's wedding. HORATIO Indeed, my lord, it follow'd hard upon. HAMLET Thrift, thrift, Horatio! the funeral baked meats Did coldly furnish forth the marriage tables. Would I had met my dearest foe in heaven Or ever I had seen that day, Horatio! My father!--methinks I see my father. HORATIO Where, my lord? HAMLET In my mind's eye, Horatio. HORATIO I saw him once; he was a goodly king. HAMLET He was a man, take him for all in all, I shall not look upon his like again. HORATIO My lord, I think I saw him yesternight. HAMLET Saw? who? HORATIO My lord, the king your father. HAMLET The king my father! HORATIO Season your admiration for awhile With an attent ear, till I may deliver, Upon the witness of these gentlemen, This marvel to you. HAMLET For God's love, let me hear. HORATIO Two nights together had these gentlemen, Marcellus and Bernardo, on their watch, In the dead vast and middle of the night, Been thus encounter'd. A figure like your father, Armed at point exactly, cap-a-pe, Appears before them, and with solemn march Goes slow and stately by them: thrice he walk'd By their oppress'd and fear-surprised eyes, Within his truncheon's length; whilst they, distilled Almost to jelly with the act of fear, Stand dumb and speak not to him. This to me In dreadful secrecy impart they did; And I with them the third night kept the watch; Where, as they had deliver'd, both in time, Form of the thing, each word made true and good, The apparition comes: I knew your father; These hands are not more like. HAMLET But where was this? MARCELLUS My lord, upon the platform where we watch'd. HAMLET Did you not speak to it? HORATIO My lord, I did; But answer made it none: yet once methought It lifted up its head and did address Itself to motion, like as it would speak; But even then the morning cock crew loud, And at the sound it shrunk in haste away, And vanish'd from our sight. HAMLET 'Tis very strange. HORATIO As I do live, my honour'd lord, 'tis true; And we did think it writ down in our duty To let you know of it. HAMLET Indeed, indeed, sirs, but this troubles me. Hold you the watch to-night? MARCELLUS BERNARDO We do, my lord. HAMLET Arm'd, say you? MARCELLUS BERNARDO Arm'd, my lord. HAMLET From top to toe? MARCELLUS BERNARDO My lord, from head to foot. HAMLET Then saw you not his face? HORATIO O, yes, my lord; he wore his beaver up. HAMLET What, look'd he frowningly? HORATIO A countenance more in sorrow than in anger. HAMLET Pale or red? HORATIO Nay, very pale. HAMLET And fix'd his eyes upon you? HORATIO Most constantly. HAMLET I would I had been there. HORATIO It would have much amazed you. HAMLET Very like, very like. Stay'd it long? HORATIO While one with moderate haste might tell a hundred. MARCELLUS BERNARDO Longer, longer. HORATIO Not when I saw't. HAMLET His beard was grizzled--no? HORATIO It was, as I have seen it in his life, A sable silver'd. HAMLET I will watch to-night; Perchance 'twill walk again. HORATIO I warrant it will. HAMLET If it assume my noble father's person, I'll speak to it, though hell itself should gape And bid me hold my peace. I pray you all, If you have hitherto conceal'd this sight, Let it be tenable in your silence still; And whatsoever else shall hap to-night, Give it an understanding, but no tongue: I will requite your loves. So, fare you well: Upon the platform, 'twixt eleven and twelve, I'll visit you. All Our duty to your honour. HAMLET Your loves, as mine to you: farewell. Exeunt all but HAMLET My father's spirit in arms! all is not well; I doubt some foul play: would the night were come! Till then sit still, my soul: foul deeds will rise, Though all the earth o'erwhelm them, to men's eyes. Exit SCENE III. A room in Polonius' house. Enter LAERTES and OPHELIA LAERTES My necessaries are embark'd: farewell: And, sister, as the winds give benefit And convoy is assistant, do not sleep, But let me hear from you. OPHELIA Do you doubt that? LAERTES For Hamlet and the trifling of his favour, Hold it a fashion and a toy in blood, A violet in the youth of primy nature, Forward, not permanent, sweet, not lasting, The perfume and suppliance of a minute; No more. OPHELIA No more but so? LAERTES Think it no more; For nature, crescent, does not grow alone In thews and bulk, but, as this temple waxes, The inward service of the mind and soul Grows wide withal. Perhaps he loves you now, And now no soil nor cautel doth besmirch The virtue of his will: but you must fear, His greatness weigh'd, his will is not his own; For he himself is subject to his birth: He may not, as unvalued persons do, Carve for himself; for on his choice depends The safety and health of this whole state; And therefore must his choice be circumscribed Unto the voice and yielding of that body Whereof he is the head. Then if he says he loves you, It fits your wisdom so far to believe it As he in his particular act and place May give his saying deed; which is no further Than the main voice of Denmark goes withal. Then weigh what loss your honour may sustain, If with too credent ear you list his songs, Or lose your heart, or your chaste treasure open To his unmaster'd importunity. Fear it, Ophelia, fear it, my dear sister, And keep you in the rear of your affection, Out of the shot and danger of desire. The chariest maid is prodigal enough, If she unmask her beauty to the moon: Virtue itself 'scapes not calumnious strokes: The canker galls the infants of the spring, Too oft before their buttons be disclosed, And in the morn and liquid dew of youth Contagious blastments are most imminent. Be wary then; best safety lies in fear: Youth to itself rebels, though none else near. OPHELIA I shall the effect of this good lesson keep, As watchman to my heart. But, good my brother, Do not, as some ungracious pastors do, Show me the steep and thorny way to heaven; Whiles, like a puff'd and reckless libertine, Himself the primrose path of dalliance treads, And recks not his own rede. LAERTES O, fear me not. I stay too long: but here my father comes. Enter POLONIUS A double blessing is a double grace, Occasion smiles upon a second leave. LORD POLONIUS Yet here, Laertes! aboard, aboard, for shame! The wind sits in the shoulder of your sail, And you are stay'd for. There; my blessing with thee! And these few precepts in thy memory See thou character. Give thy thoughts no tongue, Nor any unproportioned thought his act. Be thou familiar, but by no means vulgar. Those friends thou hast, and their adoption tried, Grapple them to thy soul with hoops of steel; But do not dull thy palm with entertainment Of each new-hatch'd, unfledged comrade. Beware Of entrance to a quarrel, but being in, Bear't that the opposed may beware of thee. Give every man thy ear, but few thy voice; Take each man's censure, but reserve thy judgment. Costly thy habit as thy purse can buy, But not express'd in fancy; rich, not gaudy; For the apparel oft proclaims the man, And they in France of the best rank and station Are of a most select and generous chief in that. Neither a borrower nor a lender be; For loan oft loses both itself and friend, And borrowing dulls the edge of husbandry. This above all: to thine ownself be true, And it must follow, as the night the day, Thou canst not then be false to any man. Farewell: my blessing season this in thee! LAERTES Most humbly do I take my leave, my lord. LORD POLONIUS The time invites you; go; your servants tend. LAERTES Farewell, Ophelia; and remember well What I have said to you. OPHELIA 'Tis in my memory lock'd, And you yourself shall keep the key of it. LAERTES Farewell. Exit LORD POLONIUS What is't, Ophelia, be hath said to you? OPHELIA So please you, something touching the Lord Hamlet. LORD POLONIUS Marry, well bethought: 'Tis told me, he hath very oft of late Given private time to you; and you yourself Have of your audience been most free and bounteous: If it be so, as so 'tis put on me, And that in way of caution, I must tell you, You do not understand yourself so clearly As it behoves my daughter and your honour. What is between you? give me up the truth. OPHELIA He hath, my lord, of late made many tenders Of his affection to me. LORD POLONIUS Affection! pooh! you speak like a green girl, Unsifted in such perilous circumstance. Do you believe his tenders, as you call them? OPHELIA I do not know, my lord, what I should think. LORD POLONIUS Marry, I'll teach you: think yourself a baby; That you have ta'en these tenders for true pay, Which are not sterling. Tender yourself more dearly; Or--not to crack the wind of the poor phrase, Running it thus--you'll tender me a fool. OPHELIA My lord, he hath importuned me with love In honourable fashion. LORD POLONIUS Ay, fashion you may call it; go to, go to. OPHELIA And hath given countenance to his speech, my lord, With almost all the holy vows of heaven. LORD POLONIUS Ay, springes to catch woodcocks. I do know, When the blood burns, how prodigal the soul Lends the tongue vows: these blazes, daughter, Giving more light than heat, extinct in both, Even in their promise, as it is a-making, You must not take for fire. From this time Be somewhat scanter of your maiden presence; Set your entreatments at a higher rate Than a command to parley. For Lord Hamlet, Believe so much in him, that he is young And with a larger tether may he walk Than may be given you: in few, Ophelia, Do not believe his vows; for they are brokers, Not of that dye which their investments show, But mere implorators of unholy suits, Breathing like sanctified and pious bawds, The better to beguile. This is for all: I would not, in plain terms, from this time forth, Have you so slander any moment leisure, As to give words or talk with the Lord Hamlet. Look to't, I charge you: come your ways. OPHELIA I shall obey, my lord. Exeunt SCENE IV. The platform. Enter HAMLET, HORATIO, and MARCELLUS HAMLET The air bites shrewdly; it is very cold. HORATIO It is a nipping and an eager air. HAMLET What hour now? HORATIO I think it lacks of twelve. HAMLET No, it is struck. HORATIO Indeed? I heard it not: then it draws near the season Wherein the spirit held his wont to walk. A flourish of trumpets, and ordnance shot off, within What does this mean, my lord? HAMLET The king doth wake to-night and takes his rouse, Keeps wassail, and the swaggering up-spring reels; And, as he drains his draughts of Rhenish down, The kettle-drum and trumpet thus bray out The triumph of his pledge. HORATIO Is it a custom? HAMLET Ay, marry, is't: But to my mind, though I am native here And to the manner born, it is a custom More honour'd in the breach than the observance. This heavy-headed revel east and west Makes us traduced and tax'd of other nations: They clepe us drunkards, and with swinish phrase Soil our addition; and indeed it takes From our achievements, though perform'd at height, The pith and marrow of our attribute. So, oft it chances in particular men, That for some vicious mole of nature in them, As, in their birth--wherein they are not guilty, Since nature cannot choose his origin-- By the o'ergrowth of some complexion, Oft breaking down the pales and forts of reason, Or by some habit that too much o'er-leavens The form of plausive manners, that these men, Carrying, I say, the stamp of one defect, Being nature's livery, or fortune's star,-- Their virtues else--be they as pure as grace, As infinite as man may undergo-- Shall in the general censure take corruption From that particular fault: the dram of eale Doth all the noble substance of a doubt To his own scandal. HORATIO Look, my lord, it comes! Enter Ghost HAMLET Angels and ministers of grace defend us! Be thou a spirit of health or goblin damn'd, Bring with thee airs from heaven or blasts from hell, Be thy intents wicked or charitable, Thou comest in such a questionable shape That I will speak to thee: I'll call thee Hamlet, King, father, royal Dane: O, answer me! Let me not burst in ignorance; but tell Why thy canonized bones, hearsed in death, Have burst their cerements; why the sepulchre, Wherein we saw thee quietly inurn'd, Hath oped his ponderous and marble jaws, To cast thee up again. What may this mean, That thou, dead corse, again in complete steel Revisit'st thus the glimpses of the moon, Making night hideous; and we fools of nature So horridly to shake our disposition With thoughts beyond the reaches of our souls? Say, why is this? wherefore? what should we do? Ghost beckons HAMLET HORATIO It beckons you to go away with it, As if it some impartment did desire To you alone. MARCELLUS Look, with what courteous action It waves you to a more removed ground: But do not go with it. HORATIO No, by no means. HAMLET It will not speak; then I will follow it. HORATIO Do not, my lord. HAMLET Why, what should be the fear? I do not set my life in a pin's fee; And for my soul, what can it do to that, Being a thing immortal as itself? It waves me forth again: I'll follow it. HORATIO What if it tempt you toward the flood, my lord, Or to the dreadful summit of the cliff That beetles o'er his base into the sea, And there assume some other horrible form, Which might deprive your sovereignty of reason And draw you into madness? think of it: The very place puts toys of desperation, Without more motive, into every brain That looks so many fathoms to the sea And hears it roar beneath. HAMLET It waves me still. Go on; I'll follow thee. MARCELLUS You shall not go, my lord. HAMLET Hold off your hands. HORATIO Be ruled; you shall not go. HAMLET My fate cries out, And makes each petty artery in this body As hardy as the Nemean lion's nerve. Still am I call'd. Unhand me, gentlemen. By heaven, I'll make a ghost of him that lets me! I say, away! Go on; I'll follow thee. Exeunt Ghost and HAMLET HORATIO He waxes desperate with imagination. MARCELLUS Let's follow; 'tis not fit thus to obey him. HORATIO Have after. To what issue will this come? MARCELLUS Something is rotten in the state of Denmark. HORATIO Heaven will direct it. MARCELLUS Nay, let's follow him. Exeunt SCENE V. Another part of the platform. Enter GHOST and HAMLET HAMLET Where wilt thou lead me? speak; I'll go no further. Ghost Mark me. HAMLET I will. Ghost My hour is almost come, When I to sulphurous and tormenting flames Must render up myself. HAMLET Alas, poor ghost! Ghost Pity me not, but lend thy serious hearing To what I shall unfold. HAMLET Speak; I am bound to hear. Ghost So art thou to revenge, when thou shalt hear. HAMLET What? Ghost I am thy father's spirit, Doom'd for a certain term to walk the night, And for the day confined to fast in fires, Till the foul crimes done in my days of nature Are burnt and purged away. But that I am forbid To tell the secrets of my prison-house, I could a tale unfold whose lightest word Would harrow up thy soul, freeze thy young blood, Make thy two eyes, like stars, start from their spheres, Thy knotted and combined locks to part And each particular hair to stand on end, Like quills upon the fretful porpentine: But this eternal blazon must not be To ears of flesh and blood. List, list, O, list! If thou didst ever thy dear father love-- HAMLET O God! Ghost Revenge his foul and most unnatural murder. HAMLET Murder! Ghost Murder most foul, as in the best it is; But this most foul, strange and unnatural. HAMLET Haste me to know't, that I, with wings as swift As meditation or the thoughts of love, May sweep to my revenge. Ghost I find thee apt; And duller shouldst thou be than the fat weed That roots itself in ease on Lethe wharf, Wouldst thou not stir in this. Now, Hamlet, hear: 'Tis given out that, sleeping in my orchard, A serpent stung me; so the whole ear of Denmark Is by a forged process of my death Rankly abused: but know, thou noble youth, The serpent that did sting thy father's life Now wears his crown. HAMLET O my prophetic soul! My uncle! Ghost Ay, that incestuous, that adulterate beast, With witchcraft of his wit, with traitorous gifts,-- O wicked wit and gifts, that have the power So to seduce!--won to his shameful lust The will of my most seeming-virtuous queen: O Hamlet, what a falling-off was there! From me, whose love was of that dignity That it went hand in hand even with the vow I made to her in marriage, and to decline Upon a wretch whose natural gifts were poor To those of mine! But virtue, as it never will be moved, Though lewdness court it in a shape of heaven, So lust, though to a radiant angel link'd, Will sate itself in a celestial bed, And prey on garbage. But, soft! methinks I scent the morning air; Brief let me be. Sleeping within my orchard, My custom always of the afternoon, Upon my secure hour thy uncle stole, With juice of cursed hebenon in a vial, And in the porches of my ears did pour The leperous distilment; whose effect Holds such an enmity with blood of man That swift as quicksilver it courses through The natural gates and alleys of the body, And with a sudden vigour doth posset And curd, like eager droppings into milk, The thin and wholesome blood: so did it mine; And a most instant tetter bark'd about, Most lazar-like, with vile and loathsome crust, All my smooth body. Thus was I, sleeping, by a brother's hand Of life, of crown, of queen, at once dispatch'd: Cut off even in the blossoms of my sin, Unhousel'd, disappointed, unanel'd, No reckoning made, but sent to my account With all my imperfections on my head: O, horrible! O, horrible! most horrible! If thou hast nature in thee, bear it not; Let not the royal bed of Denmark be A couch for luxury and damned incest. But, howsoever thou pursuest this act, Taint not thy mind, nor let thy soul contrive Against thy mother aught: leave her to heaven And to those thorns that in her bosom lodge, To prick and sting her. Fare thee well at once! The glow-worm shows the matin to be near, And 'gins to pale his uneffectual fire: Adieu, adieu! Hamlet, remember me. Exit HAMLET O all you host of heaven! O earth! what else? And shall I couple hell? O, fie! Hold, hold, my heart; And you, my sinews, grow not instant old, But bear me stiffly up. Remember thee! Ay, thou poor ghost, while memory holds a seat In this distracted globe. Remember thee! Yea, from the table of my memory I'll wipe away all trivial fond records, All saws of books, all forms, all pressures past, That youth and observation copied there; And thy commandment all alone shall live Within the book and volume of my brain, Unmix'd with baser matter: yes, by heaven! O most pernicious woman! O villain, villain, smiling, damned villain! My tables,--meet it is I set it down, That one may smile, and smile, and be a villain; At least I'm sure it may be so in Denmark: Writing So, uncle, there you are. Now to my word; It is 'Adieu, adieu! remember me.' I have sworn 't. MARCELLUS HORATIO Within My lord, my lord,-- MARCELLUS Within Lord Hamlet,-- HORATIO Within Heaven secure him! HAMLET So be it! HORATIO Within Hillo, ho, ho, my lord! HAMLET Hillo, ho, ho, boy! come, bird, come. Enter HORATIO and MARCELLUS MARCELLUS How is't, my noble lord? HORATIO What news, my lord? HAMLET O, wonderful! HORATIO Good my lord, tell it. HAMLET No; you'll reveal it. HORATIO Not I, my lord, by heaven. MARCELLUS Nor I, my lord. HAMLET How say you, then; would heart of man once think it? But you'll be secret? HORATIO MARCELLUS Ay, by heaven, my lord. HAMLET There's ne'er a villain dwelling in all Denmark But he's an arrant knave. HORATIO There needs no ghost, my lord, come from the grave To tell us this. HAMLET Why, right; you are i' the right; And so, without more circumstance at all, I hold it fit that we shake hands and part: You, as your business and desire shall point you; For every man has business and desire, Such as it is; and for mine own poor part, Look you, I'll go pray. HORATIO These are but wild and whirling words, my lord. HAMLET I'm sorry they offend you, heartily; Yes, 'faith heartily. HORATIO There's no offence, my lord. HAMLET Yes, by Saint Patrick, but there is, Horatio, And much offence too. Touching this vision here, It is an honest ghost, that let me tell you: For your desire to know what is between us, O'ermaster 't as you may. And now, good friends, As you are friends, scholars and soldiers, Give me one poor request. HORATIO What is't, my lord? we will. HAMLET Never make known what you have seen to-night. HORATIO MARCELLUS My lord, we will not. HAMLET Nay, but swear't. HORATIO In faith, My lord, not I. MARCELLUS Nor I, my lord, in faith. HAMLET Upon my sword. MARCELLUS We have sworn, my lord, already. HAMLET Indeed, upon my sword, indeed. Ghost Beneath Swear. HAMLET Ah, ha, boy! say'st thou so? art thou there, truepenny? Come on--you hear this fellow in the cellarage-- Consent to swear. HORATIO Propose the oath, my lord. HAMLET Never to speak of this that you have seen, Swear by my sword. Ghost Beneath Swear. HAMLET Hic et ubique? then we'll shift our ground. Come hither, gentlemen, And lay your hands again upon my sword: Never to speak of this that you have heard, Swear by my sword. Ghost Beneath Swear. HAMLET Well said, old mole! canst work i' the earth so fast? A worthy pioner! Once more remove, good friends. HORATIO O day and night, but this is wondrous strange! HAMLET And therefore as a stranger give it welcome. There are more things in heaven and earth, Horatio, Than are dreamt of in your philosophy. But come; Here, as before, never, so help you mercy, How strange or odd soe'er I bear myself, As I perchance hereafter shall think meet To put an antic disposition on, That you, at such times seeing me, never shall, With arms encumber'd thus, or this headshake, Or by pronouncing of some doubtful phrase, As 'Well, well, we know,' or 'We could, an if we would,' Or 'If we list to speak,' or 'There be, an if they might,' Or such ambiguous giving out, to note That you know aught of me: this not to do, So grace and mercy at your most need help you, Swear. Ghost Beneath Swear. HAMLET Rest, rest, perturbed spirit! They swear So, gentlemen, With all my love I do commend me to you: And what so poor a man as Hamlet is May do, to express his love and friending to you, God willing, shall not lack. Let us go in together; And still your fingers on your lips, I pray. The time is out of joint: O cursed spite, That ever I was born to set it right! Nay, come, let's go together. Exeunt ACT II SCENE I. A room in POLONIUS' house. Enter POLONIUS and REYNALDO LORD POLONIUS Give him this money and these notes, Reynaldo. REYNALDO I will, my lord. LORD POLONIUS You shall do marvellous wisely, good Reynaldo, Before you visit him, to make inquire Of his behavior. REYNALDO My lord, I did intend it. LORD POLONIUS Marry, well said; very well said. Look you, sir, Inquire me first what Danskers are in Paris; And how, and who, what means, and where they keep, What company, at what expense; and finding By this encompassment and drift of question That they do know my son, come you more nearer Than your particular demands will touch it: Take you, as 'twere, some distant knowledge of him; As thus, 'I know his father and his friends, And in part him: ' do you mark this, Reynaldo? REYNALDO Ay, very well, my lord. LORD POLONIUS 'And in part him; but' you may say 'not well: But, if't be he I mean, he's very wild; Addicted so and so:' and there put on him What forgeries you please; marry, none so rank As may dishonour him; take heed of that; But, sir, such wanton, wild and usual slips As are companions noted and most known To youth and liberty. REYNALDO As gaming, my lord. LORD POLONIUS Ay, or drinking, fencing, swearing, quarrelling, Drabbing: you may go so far. REYNALDO My lord, that would dishonour him. LORD POLONIUS 'Faith, no; as you may season it in the charge You must not put another scandal on him, That he is open to incontinency; That's not my meaning: but breathe his faults so quaintly That they may seem the taints of liberty, The flash and outbreak of a fiery mind, A savageness in unreclaimed blood, Of general assault. REYNALDO But, my good lord,-- LORD POLONIUS Wherefore should you do this? REYNALDO Ay, my lord, I would know that. LORD POLONIUS Marry, sir, here's my drift; And I believe, it is a fetch of wit: You laying these slight sullies on my son, As 'twere a thing a little soil'd i' the working, Mark you, Your party in converse, him you would sound, Having ever seen in the prenominate crimes The youth you breathe of guilty, be assured He closes with you in this consequence; 'Good sir,' or so, or 'friend,' or 'gentleman,' According to the phrase or the addition Of man and country. REYNALDO Very good, my lord. LORD POLONIUS And then, sir, does he this--he does--what was I about to say? By the mass, I was about to say something: where did I leave? REYNALDO At 'closes in the consequence,' at 'friend or so,' and 'gentleman.' LORD POLONIUS At 'closes in the consequence,' ay, marry; He closes thus: 'I know the gentleman; I saw him yesterday, or t' other day, Or then, or then; with such, or such; and, as you say, There was a' gaming; there o'ertook in's rouse; There falling out at tennis:' or perchance, 'I saw him enter such a house of sale,' Videlicet, a brothel, or so forth. See you now; Your bait of falsehood takes this carp of truth: And thus do we of wisdom and of reach, With windlasses and with assays of bias, By indirections find directions out: So by my former lecture and advice, Shall you my son. You have me, have you not? REYNALDO My lord, I have. LORD POLONIUS God be wi' you; fare you well. REYNALDO Good my lord! LORD POLONIUS Observe his inclination in yourself. REYNALDO I shall, my lord. LORD POLONIUS And let him ply his music. REYNALDO Well, my lord. LORD POLONIUS Farewell! Exit REYNALDO Enter OPHELIA How now, Ophelia! what's the matter? OPHELIA O, my lord, my lord, I have been so affrighted! LORD POLONIUS With what, i' the name of God? OPHELIA My lord, as I was sewing in my closet, Lord Hamlet, with his doublet all unbraced; No hat upon his head; his stockings foul'd, Ungarter'd, and down-gyved to his ancle; Pale as his shirt; his knees knocking each other; And with a look so piteous in purport As if he had been loosed out of hell To speak of horrors,--he comes before me. LORD POLONIUS Mad for thy love? OPHELIA My lord, I do not know; But truly, I do fear it. LORD POLONIUS What said he? OPHELIA He took me by the wrist and held me hard; Then goes he to the length of all his arm; And, with his other hand thus o'er his brow, He falls to such perusal of my face As he would draw it. Long stay'd he so; At last, a little shaking of mine arm And thrice his head thus waving up and down, He raised a sigh so piteous and profound As it did seem to shatter all his bulk And end his being: that done, he lets me go: And, with his head over his shoulder turn'd, He seem'd to find his way without his eyes; For out o' doors he went without their helps, And, to the last, bended their light on me. LORD POLONIUS Come, go with me: I will go seek the king. This is the very ecstasy of love, Whose violent property fordoes itself And leads the will to desperate undertakings As oft as any passion under heaven That does afflict our natures. I am sorry. What, have you given him any hard words of late? OPHELIA No, my good lord, but, as you did command, I did repel his fetters and denied His access to me. LORD POLONIUS That hath made him mad. I am sorry that with better heed and judgment I had not quoted him: I fear'd he did but trifle, And meant to wreck thee; but, beshrew my jealousy! By heaven, it is as proper to our age To cast beyond ourselves in our opinions As it is common for the younger sort To lack discretion. Come, go we to the king: This must be known; which, being kept close, might move More grief to hide than hate to utter love. Exeunt SCENE II. A room in the castle. Enter KING CLAUDIUS, QUEEN GERTRUDE, ROSENCRANTZ, GUILDENSTERN, and Attendants KING CLAUDIUS Welcome, dear Rosencrantz and Guildenstern! Moreover that we much did long to see you, The need we have to use you did provoke Our hasty sending. Something have you heard Of Hamlet's transformation; so call it, Sith nor the exterior nor the inward man Resembles that it was. What it should be, More than his father's death, that thus hath put him So much from the understanding of himself, I cannot dream of: I entreat you both, That, being of so young days brought up with him, And sith so neighbour'd to his youth and havior, That you vouchsafe your rest here in our court Some little time: so by your companies To draw him on to pleasures, and to gather, So much as from occasion you may glean, Whether aught, to us unknown, afflicts him thus, That, open'd, lies within our remedy. QUEEN GERTRUDE Good gentlemen, he hath much talk'd of you; And sure I am two men there are not living To whom he more adheres. If it will please you To show us so much gentry and good will As to expend your time with us awhile, For the supply and profit of our hope, Your visitation shall receive such thanks As fits a king's remembrance. ROSENCRANTZ Both your majesties Might, by the sovereign power you have of us, Put your dread pleasures more into command Than to entreaty. GUILDENSTERN But we both obey, And here give up ourselves, in the full bent To lay our service freely at your feet, To be commanded. KING CLAUDIUS Thanks, Rosencrantz and gentle Guildenstern. QUEEN GERTRUDE Thanks, Guildenstern and gentle Rosencrantz: And I beseech you instantly to visit My too much changed son. Go, some of you, And bring these gentlemen where Hamlet is. GUILDENSTERN Heavens make our presence and our practises Pleasant and helpful to him! QUEEN GERTRUDE Ay, amen! Exeunt ROSENCRANTZ, GUILDENSTERN, and some Attendants Enter POLONIUS LORD POLONIUS The ambassadors from Norway, my good lord, Are joyfully return'd. KING CLAUDIUS Thou still hast been the father of good news. LORD POLONIUS Have I, my lord? I assure my good liege, I hold my duty, as I hold my soul, Both to my God and to my gracious king: And I do think, or else this brain of mine Hunts not the trail of policy so sure As it hath used to do, that I have found The very cause of Hamlet's lunacy. KING CLAUDIUS O, speak of that; that do I long to hear. LORD POLONIUS Give first admittance to the ambassadors; My news shall be the fruit to that great feast. KING CLAUDIUS Thyself do grace to them, and bring them in. Exit POLONIUS He tells me, my dear Gertrude, he hath found The head and source of all your son's distemper. QUEEN GERTRUDE I doubt it is no other but the main; His father's death, and our o'erhasty marriage. KING CLAUDIUS Well, we shall sift him. Re-enter POLONIUS, with VOLTIMAND and CORNELIUS Welcome, my good friends! Say, Voltimand, what from our brother Norway? VOLTIMAND Most fair return of greetings and desires. Upon our first, he sent out to suppress His nephew's levies; which to him appear'd To be a preparation 'gainst the Polack; But, better look'd into, he truly found It was against your highness: whereat grieved, That so his sickness, age and impotence Was falsely borne in hand, sends out arrests On Fortinbras; which he, in brief, obeys; Receives rebuke from Norway, and in fine Makes vow before his uncle never more To give the assay of arms against your majesty. Whereon old Norway, overcome with joy, Gives him three thousand crowns in annual fee, And his commission to employ those soldiers, So levied as before, against the Polack: With an entreaty, herein further shown, Giving a paper That it might please you to give quiet pass Through your dominions for this enterprise, On such regards of safety and allowance As therein are set down. KING CLAUDIUS It likes us well; And at our more consider'd time well read, Answer, and think upon this business. Meantime we thank you for your well-took labour: Go to your rest; at night we'll feast together: Most welcome home! Exeunt VOLTIMAND and CORNELIUS LORD POLONIUS This business is well ended. My liege, and madam, to expostulate What majesty should be, what duty is, Why day is day, night night, and time is time, Were nothing but to waste night, day and time. Therefore, since brevity is the soul of wit, And tediousness the limbs and outward flourishes, I will be brief: your noble son is mad: Mad call I it; for, to define true madness, What is't but to be nothing else but mad? But let that go. QUEEN GERTRUDE More matter, with less art. LORD POLONIUS Madam, I swear I use no art at all. That he is mad, 'tis true: 'tis true 'tis pity; And pity 'tis 'tis true: a foolish figure; But farewell it, for I will use no art. Mad let us grant him, then: and now remains That we find out the cause of this effect, Or rather say, the cause of this defect, For this effect defective comes by cause: Thus it remains, and the remainder thus. Perpend. I have a daughter--have while she is mine-- Who, in her duty and obedience, mark, Hath given me this: now gather, and surmise. Reads 'To the celestial and my soul's idol, the most beautified Ophelia,'-- That's an ill phrase, a vile phrase; 'beautified' is a vile phrase: but you shall hear. Thus: Reads 'In her excellent white bosom, these, &c.' QUEEN GERTRUDE Came this from Hamlet to her? LORD POLONIUS Good madam, stay awhile; I will be faithful. Reads 'Doubt thou the stars are fire; Doubt that the sun doth move; Doubt truth to be a liar; But never doubt I love. 'O dear Ophelia, I am ill at these numbers; I have not art to reckon my groans: but that I love thee best, O most best, believe it. Adieu. 'Thine evermore most dear lady, whilst this machine is to him, HAMLET.' This, in obedience, hath my daughter shown me, And more above, hath his solicitings, As they fell out by time, by means and place, All given to mine ear. KING CLAUDIUS But how hath she Received his love? LORD POLONIUS What do you think of me? KING CLAUDIUS As of a man faithful and honourable. LORD POLONIUS I would fain prove so. But what might you think, When I had seen this hot love on the wing-- As I perceived it, I must tell you that, Before my daughter told me--what might you, Or my dear majesty your queen here, think, If I had play'd the desk or table-book, Or given my heart a winking, mute and dumb, Or look'd upon this love with idle sight; What might you think? No, I went round to work, And my young mistress thus I did bespeak: 'Lord Hamlet is a prince, out of thy star; This must not be:' and then I precepts gave her, That she should lock herself from his resort, Admit no messengers, receive no tokens. Which done, she took the fruits of my advice; And he, repulsed--a short tale to make-- Fell into a sadness, then into a fast, Thence to a watch, thence into a weakness, Thence to a lightness, and, by this declension, Into the madness wherein now he raves, And all we mourn for. KING CLAUDIUS Do you think 'tis this? QUEEN GERTRUDE It may be, very likely. LORD POLONIUS Hath there been such a time--I'd fain know that-- That I have positively said 'Tis so,' When it proved otherwise? KING CLAUDIUS Not that I know. LORD POLONIUS Pointing to his head and shoulder Take this from this, if this be otherwise: If circumstances lead me, I will find Where truth is hid, though it were hid indeed Within the centre. KING CLAUDIUS How may we try it further? LORD POLONIUS You know, sometimes he walks four hours together Here in the lobby. QUEEN GERTRUDE So he does indeed. LORD POLONIUS At such a time I'll loose my daughter to him: Be you and I behind an arras then; Mark the encounter: if he love her not And be not from his reason fall'n thereon, Let me be no assistant for a state, But keep a farm and carters. KING CLAUDIUS We will try it. QUEEN GERTRUDE But, look, where sadly the poor wretch comes reading. LORD POLONIUS Away, I do beseech you, both away: I'll board him presently. Exeunt KING CLAUDIUS, QUEEN GERTRUDE, and Attendants Enter HAMLET, reading O, give me leave: How does my good Lord Hamlet? HAMLET Well, God-a-mercy. LORD POLONIUS Do you know me, my lord? HAMLET Excellent well; you are a fishmonger. LORD POLONIUS Not I, my lord. HAMLET Then I would you were so honest a man. LORD POLONIUS Honest, my lord! HAMLET Ay, sir; to be honest, as this world goes, is to be one man picked out of ten thousand. LORD POLONIUS That's very true, my lord. HAMLET For if the sun breed maggots in a dead dog, being a god kissing carrion,--Have you a daughter? LORD POLONIUS I have, my lord. HAMLET Let her not walk i' the sun: conception is a blessing: but not as your daughter may conceive. Friend, look to 't. LORD POLONIUS Aside How say you by that? Still harping on my daughter: yet he knew me not at first; he said I was a fishmonger: he is far gone, far gone: and truly in my youth I suffered much extremity for love; very near this. I'll speak to him again. What do you read, my lord? HAMLET Words, words, words. LORD POLONIUS What is the matter, my lord? HAMLET Between who? LORD POLONIUS I mean, the matter that you read, my lord. HAMLET Slanders, sir: for the satirical rogue says here that old men have grey beards, that their faces are wrinkled, their eyes purging thick amber and plum-tree gum and that they have a plentiful lack of wit, together with most weak hams: all which, sir, though I most powerfully and potently believe, yet I hold it not honesty to have it thus set down, for yourself, sir, should be old as I am, if like a crab you could go backward. LORD POLONIUS Aside Though this be madness, yet there is method in 't. Will you walk out of the air, my lord? HAMLET Into my grave. LORD POLONIUS Indeed, that is out o' the air. Aside How pregnant sometimes his replies are! a happiness that often madness hits on, which reason and sanity could not so prosperously be delivered of. I will leave him, and suddenly contrive the means of meeting between him and my daughter.--My honourable lord, I will most humbly take my leave of you. HAMLET You cannot, sir, take from me any thing that I will more willingly part withal: except my life, except my life, except my life. LORD POLONIUS Fare you well, my lord. HAMLET These tedious old fools! Enter ROSENCRANTZ and GUILDENSTERN LORD POLONIUS You go to seek the Lord Hamlet; there he is. ROSENCRANTZ To POLONIUS God save you, sir! Exit POLONIUS GUILDENSTERN My honoured lord! ROSENCRANTZ My most dear lord! HAMLET My excellent good friends! How dost thou, Guildenstern? Ah, Rosencrantz! Good lads, how do ye both? ROSENCRANTZ As the indifferent children of the earth. GUILDENSTERN Happy, in that we are not over-happy; On fortune's cap we are not the very button. HAMLET Nor the soles of her shoe? ROSENCRANTZ Neither, my lord. HAMLET Then you live about her waist, or in the middle of her favours? GUILDENSTERN 'Faith, her privates we. HAMLET In the secret parts of fortune? O, most true; she is a strumpet. What's the news? ROSENCRANTZ None, my lord, but that the world's grown honest. HAMLET Then is doomsday near: but your news is not true. Let me question more in particular: what have you, my good friends, deserved at the hands of fortune, that she sends you to prison hither? GUILDENSTERN Prison, my lord! HAMLET Denmark's a prison. ROSENCRANTZ Then is the world one. HAMLET A goodly one; in which there are many confines, wards and dungeons, Denmark being one o' the worst. ROSENCRANTZ We think not so, my lord. HAMLET Why, then, 'tis none to you; for there is nothing either good or bad, but thinking makes it so: to me it is a prison. ROSENCRANTZ Why then, your ambition makes it one; 'tis too narrow for your mind. HAMLET O God, I could be bounded in a nut shell and count myself a king of infinite space, were it not that I have bad dreams. GUILDENSTERN Which dreams indeed are ambition, for the very substance of the ambitious is merely the shadow of a dream. HAMLET A dream itself is but a shadow. ROSENCRANTZ Truly, and I hold ambition of so airy and light a quality that it is but a shadow's shadow. HAMLET Then are our beggars bodies, and our monarchs and outstretched heroes the beggars' shadows. Shall we to the court? for, by my fay, I cannot reason. ROSENCRANTZ GUILDENSTERN We'll wait upon you. HAMLET No such matter: I will not sort you with the rest of my servants, for, to speak to you like an honest man, I am most dreadfully attended. But, in the beaten way of friendship, what make you at Elsinore? ROSENCRANTZ To visit you, my lord; no other occasion. HAMLET Beggar that I am, I am even poor in thanks; but I thank you: and sure, dear friends, my thanks are too dear a halfpenny. Were you not sent for? Is it your own inclining? Is it a free visitation? Come, deal justly with me: come, come; nay, speak. GUILDENSTERN What should we say, my lord? HAMLET Why, any thing, but to the purpose. You were sent for; and there is a kind of confession in your looks which your modesties have not craft enough to colour: I know the good king and queen have sent for you. ROSENCRANTZ To what end, my lord? HAMLET That you must teach me. But let me conjure you, by the rights of our fellowship, by the consonancy of our youth, by the obligation of our ever-preserved love, and by what more dear a better proposer could charge you withal, be even and direct with me, whether you were sent for, or no? ROSENCRANTZ Aside to GUILDENSTERN What say you? HAMLET Aside Nay, then, I have an eye of you.--If you love me, hold not off. GUILDENSTERN My lord, we were sent for. HAMLET I will tell you why; so shall my anticipation prevent your discovery, and your secrecy to the king and queen moult no feather. I have of late--but wherefore I know not--lost all my mirth, forgone all custom of exercises; and indeed it goes so heavily with my disposition that this goodly frame, the earth, seems to me a sterile promontory, this most excellent canopy, the air, look you, this brave o'erhanging firmament, this majestical roof fretted with golden fire, why, it appears no other thing to me than a foul and pestilent congregation of vapours. What a piece of work is a man! how noble in reason! how infinite in faculty! in form and moving how express and admirable! in action how like an angel! in apprehension how like a god! the beauty of the world! the paragon of animals! And yet, to me, what is this quintessence of dust? man delights not me: no, nor woman neither, though by your smiling you seem to say so. ROSENCRANTZ My lord, there was no such stuff in my thoughts. HAMLET Why did you laugh then, when I said 'man delights not me'? ROSENCRANTZ To think, my lord, if you delight not in man, what lenten entertainment the players shall receive from you: we coted them on the way; and hither are they coming, to offer you service. HAMLET He that plays the king shall be welcome; his majesty shall have tribute of me; the adventurous knight shall use his foil and target; the lover shall not sigh gratis; the humourous man shall end his part in peace; the clown shall make those laugh whose lungs are tickled o' the sere; and the lady shall say her mind freely, or the blank verse shall halt for't. What players are they? ROSENCRANTZ Even those you were wont to take delight in, the tragedians of the city. HAMLET How chances it they travel? their residence, both in reputation and profit, was better both ways. ROSENCRANTZ I think their inhibition comes by the means of the late innovation. HAMLET Do they hold the same estimation they did when I was in the city? are they so followed? ROSENCRANTZ No, indeed, are they not. HAMLET How comes it? do they grow rusty? ROSENCRANTZ Nay, their endeavour keeps in the wonted pace: but there is, sir, an aery of children, little eyases, that cry out on the top of question, and are most tyrannically clapped for't: these are now the fashion, and so berattle the common stages--so they call them--that many wearing rapiers are afraid of goose-quills and dare scarce come thither. HAMLET What, are they children? who maintains 'em? how are they escoted? Will they pursue the quality no longer than they can sing? will they not say afterwards, if they should grow themselves to common players--as it is most like, if their means are no better--their writers do them wrong, to make them exclaim against their own succession? ROSENCRANTZ 'Faith, there has been much to do on both sides; and the nation holds it no sin to tarre them to controversy: there was, for a while, no money bid for argument, unless the poet and the player went to cuffs in the question. HAMLET Is't possible? GUILDENSTERN O, there has been much throwing about of brains. HAMLET Do the boys carry it away? ROSENCRANTZ Ay, that they do, my lord; Hercules and his load too. HAMLET It is not very strange; for mine uncle is king of Denmark, and those that would make mows at him while my father lived, give twenty, forty, fifty, an hundred ducats a-piece for his picture in little. 'Sblood, there is something in this more than natural, if philosophy could find it out. Flourish of trumpets within GUILDENSTERN There are the players. HAMLET Gentlemen, you are welcome to Elsinore. Your hands, come then: the appurtenance of welcome is fashion and ceremony: let me comply with you in this garb, lest my extent to the players, which, I tell you, must show fairly outward, should more appear like entertainment than yours. You are welcome: but my uncle-father and aunt-mother are deceived. GUILDENSTERN In what, my dear lord? HAMLET I am but mad north-north-west: when the wind is southerly I know a hawk from a handsaw. Enter POLONIUS LORD POLONIUS Well be with you, gentlemen! HAMLET Hark you, Guildenstern; and you too: at each ear a hearer: that great baby you see there is not yet out of his swaddling-clouts. ROSENCRANTZ Happily he's the second time come to them; for they say an old man is twice a child. HAMLET I will prophesy he comes to tell me of the players; mark it. You say right, sir: o' Monday morning; 'twas so indeed. LORD POLONIUS My lord, I have news to tell you. HAMLET My lord, I have news to tell you. When Roscius was an actor in Rome,-- LORD POLONIUS The actors are come hither, my lord. HAMLET Buz, buz! LORD POLONIUS Upon mine honour,-- HAMLET Then came each actor on his ass,-- LORD POLONIUS The best actors in the world, either for tragedy, comedy, history, pastoral, pastoral-comical, historical-pastoral, tragical-historical, tragical- comical-historical-pastoral, scene individable, or poem unlimited: Seneca cannot be too heavy, nor Plautus too light. For the law of writ and the liberty, these are the only men. HAMLET O Jephthah, judge of Israel, what a treasure hadst thou! LORD POLONIUS What a treasure had he, my lord? HAMLET Why, 'One fair daughter and no more, The which he loved passing well.' LORD POLONIUS Aside Still on my daughter. HAMLET Am I not i' the right, old Jephthah? LORD POLONIUS If you call me Jephthah, my lord, I have a daughter that I love passing well. HAMLET Nay, that follows not. LORD POLONIUS What follows, then, my lord? HAMLET Why, 'As by lot, God wot,' and then, you know, 'It came to pass, as most like it was,'-- the first row of the pious chanson will show you more; for look, where my abridgement comes. Enter four or five Players You are welcome, masters; welcome, all. I am glad to see thee well. Welcome, good friends. O, my old friend! thy face is valenced since I saw thee last: comest thou to beard me in Denmark? What, my young lady and mistress! By'r lady, your ladyship is nearer to heaven than when I saw you last, by the altitude of a chopine. Pray God, your voice, like apiece of uncurrent gold, be not cracked within the ring. Masters, you are all welcome. We'll e'en to't like French falconers, fly at any thing we see: we'll have a speech straight: come, give us a taste of your quality; come, a passionate speech. First Player What speech, my lord? HAMLET I heard thee speak me a speech once, but it was never acted; or, if it was, not above once; for the play, I remember, pleased not the million; 'twas caviare to the general: but it was--as I received it, and others, whose judgments in such matters cried in the top of mine--an excellent play, well digested in the scenes, set down with as much modesty as cunning. I remember, one said there were no sallets in the lines to make the matter savoury, nor no matter in the phrase that might indict the author of affectation; but called it an honest method, as wholesome as sweet, and by very much more handsome than fine. One speech in it I chiefly loved: 'twas Aeneas' tale to Dido; and thereabout of it especially, where he speaks of Priam's slaughter: if it live in your memory, begin at this line: let me see, let me see-- 'The rugged Pyrrhus, like the Hyrcanian beast,'-- it is not so:--it begins with Pyrrhus:-- 'The rugged Pyrrhus, he whose sable arms, Black as his purpose, did the night resemble When he lay couched in the ominous horse, Hath now this dread and black complexion smear'd With heraldry more dismal; head to foot Now is he total gules; horridly trick'd With blood of fathers, mothers, daughters, sons, Baked and impasted with the parching streets, That lend a tyrannous and damned light To their lord's murder: roasted in wrath and fire, And thus o'er-sized with coagulate gore, With eyes like carbuncles, the hellish Pyrrhus Old grandsire Priam seeks.' So, proceed you. LORD POLONIUS 'Fore God, my lord, well spoken, with good accent and good discretion. First Player 'Anon he finds him Striking too short at Greeks; his antique sword, Rebellious to his arm, lies where it falls, Repugnant to command: unequal match'd, Pyrrhus at Priam drives; in rage strikes wide; But with the whiff and wind of his fell sword The unnerved father falls. Then senseless Ilium, Seeming to feel this blow, with flaming top Stoops to his base, and with a hideous crash Takes prisoner Pyrrhus' ear: for, lo! his sword, Which was declining on the milky head Of reverend Priam, seem'd i' the air to stick: So, as a painted tyrant, Pyrrhus stood, And like a neutral to his will and matter, Did nothing. But, as we often see, against some storm, A silence in the heavens, the rack stand still, The bold winds speechless and the orb below As hush as death, anon the dreadful thunder Doth rend the region, so, after Pyrrhus' pause, Aroused vengeance sets him new a-work; And never did the Cyclops' hammers fall On Mars's armour forged for proof eterne With less remorse than Pyrrhus' bleeding sword Now falls on Priam. Out, out, thou strumpet, Fortune! All you gods, In general synod 'take away her power; Break all the spokes and fellies from her wheel, And bowl the round nave down the hill of heaven, As low as to the fiends!' LORD POLONIUS This is too long. HAMLET It shall to the barber's, with your beard. Prithee, say on: he's for a jig or a tale of bawdry, or he sleeps: say on: come to Hecuba. First Player 'But who, O, who had seen the mobled queen--' HAMLET 'The mobled queen?' LORD POLONIUS That's good; 'mobled queen' is good. First Player 'Run barefoot up and down, threatening the flames With bisson rheum; a clout upon that head Where late the diadem stood, and for a robe, About her lank and all o'er-teemed loins, A blanket, in the alarm of fear caught up; Who this had seen, with tongue in venom steep'd, 'Gainst Fortune's state would treason have pronounced: But if the gods themselves did see her then When she saw Pyrrhus make malicious sport In mincing with his sword her husband's limbs, The instant burst of clamour that she made, Unless things mortal move them not at all, Would have made milch the burning eyes of heaven, And passion in the gods.' LORD POLONIUS Look, whether he has not turned his colour and has tears in's eyes. Pray you, no more. HAMLET 'Tis well: I'll have thee speak out the rest soon. Good my lord, will you see the players well bestowed? Do you hear, let them be well used; for they are the abstract and brief chronicles of the time: after your death you were better have a bad epitaph than their ill report while you live. LORD POLONIUS My lord, I will use them according to their desert. HAMLET God's bodykins, man, much better: use every man after his desert, and who should 'scape whipping? Use them after your own honour and dignity: the less they deserve, the more merit is in your bounty. Take them in. LORD POLONIUS Come, sirs. HAMLET Follow him, friends: we'll hear a play to-morrow. Exit POLONIUS with all the Players but the First Dost thou hear me, old friend; can you play the Murder of Gonzago? First Player Ay, my lord. HAMLET We'll ha't to-morrow night. You could, for a need, study a speech of some dozen or sixteen lines, which I would set down and insert in't, could you not? First Player Ay, my lord. HAMLET Very well. Follow that lord; and look you mock him not. Exit First Player My good friends, I'll leave you till night: you are welcome to Elsinore. ROSENCRANTZ Good my lord! HAMLET Ay, so, God be wi' ye; Exeunt ROSENCRANTZ and GUILDENSTERN Now I am alone. O, what a rogue and peasant slave am I! Is it not monstrous that this player here, But in a fiction, in a dream of passion, Could force his soul so to his own conceit That from her working all his visage wann'd, Tears in his eyes, distraction in's aspect, A broken voice, and his whole function suiting With forms to his conceit? and all for nothing! For Hecuba! What's Hecuba to him, or he to Hecuba, That he should weep for her? What would he do, Had he the motive and the cue for passion That I have? He would drown the stage with tears And cleave the general ear with horrid speech, Make mad the guilty and appal the free, Confound the ignorant, and amaze indeed The very faculties of eyes and ears. Yet I, A dull and muddy-mettled rascal, peak, Like John-a-dreams, unpregnant of my cause, And can say nothing; no, not for a king, Upon whose property and most dear life A damn'd defeat was made. Am I a coward? Who calls me villain? breaks my pate across? Plucks off my beard, and blows it in my face? Tweaks me by the nose? gives me the lie i' the throat, As deep as to the lungs? who does me this? Ha! 'Swounds, I should take it: for it cannot be But I am pigeon-liver'd and lack gall To make oppression bitter, or ere this I should have fatted all the region kites With this slave's offal: bloody, bawdy villain! Remorseless, treacherous, lecherous, kindless villain! O, vengeance! Why, what an ass am I! This is most brave, That I, the son of a dear father murder'd, Prompted to my revenge by heaven and hell, Must, like a whore, unpack my heart with words, And fall a-cursing, like a very drab, A scullion! Fie upon't! foh! About, my brain! I have heard That guilty creatures sitting at a play Have by the very cunning of the scene Been struck so to the soul that presently They have proclaim'd their malefactions; For murder, though it have no tongue, will speak With most miraculous organ. I'll have these players Play something like the murder of my father Before mine uncle: I'll observe his looks; I'll tent him to the quick: if he but blench, I know my course. The spirit that I have seen May be the devil: and the devil hath power To assume a pleasing shape; yea, and perhaps Out of my weakness and my melancholy, As he is very potent with such spirits, Abuses me to damn me: I'll have grounds More relative than this: the play 's the thing Wherein I'll catch the conscience of the king. Exit ACT III SCENE I. A room in the castle. Enter KING CLAUDIUS, QUEEN GERTRUDE, POLONIUS, OPHELIA, ROSENCRANTZ, and GUILDENSTERN KING CLAUDIUS And can you, by no drift of circumstance, Get from him why he puts on this confusion, Grating so harshly all his days of quiet With turbulent and dangerous lunacy? ROSENCRANTZ He does confess he feels himself distracted; But from what cause he will by no means speak. GUILDENSTERN Nor do we find him forward to be sounded, But, with a crafty madness, keeps aloof, When we would bring him on to some confession Of his true state. QUEEN GERTRUDE Did he receive you well? ROSENCRANTZ Most like a gentleman. GUILDENSTERN But with much forcing of his disposition. ROSENCRANTZ Niggard of question; but, of our demands, Most free in his reply. QUEEN GERTRUDE Did you assay him? To any pastime? ROSENCRANTZ Madam, it so fell out, that certain players We o'er-raught on the way: of these we told him; And there did seem in him a kind of joy To hear of it: they are about the court, And, as I think, they have already order This night to play before him. LORD POLONIUS 'Tis most true: And he beseech'd me to entreat your majesties To hear and see the matter. KING CLAUDIUS With all my heart; and it doth much content me To hear him so inclined. Good gentlemen, give him a further edge, And drive his purpose on to these delights. ROSENCRANTZ We shall, my lord. Exeunt ROSENCRANTZ and GUILDENSTERN KING CLAUDIUS Sweet Gertrude, leave us too; For we have closely sent for Hamlet hither, That he, as 'twere by accident, may here Affront Ophelia: Her father and myself, lawful espials, Will so bestow ourselves that, seeing, unseen, We may of their encounter frankly judge, And gather by him, as he is behaved, If 't be the affliction of his love or no That thus he suffers for. QUEEN GERTRUDE I shall obey you. And for your part, Ophelia, I do wish That your good beauties be the happy cause Of Hamlet's wildness: so shall I hope your virtues Will bring him to his wonted way again, To both your honours. OPHELIA Madam, I wish it may. Exit QUEEN GERTRUDE LORD POLONIUS Ophelia, walk you here. Gracious, so please you, We will bestow ourselves. To OPHELIA Read on this book; That show of such an exercise may colour Your loneliness. We are oft to blame in this,-- 'Tis too much proved--that with devotion's visage And pious action we do sugar o'er The devil himself. KING CLAUDIUS Aside O, 'tis too true! How smart a lash that speech doth give my conscience! The harlot's cheek, beautied with plastering art, Is not more ugly to the thing that helps it Than is my deed to my most painted word: O heavy burthen! LORD POLONIUS I hear him coming: let's withdraw, my lord. Exeunt KING CLAUDIUS and POLONIUS Enter HAMLET HAMLET To be, or not to be: that is the question: Whether 'tis nobler in the mind to suffer The slings and arrows of outrageous fortune, Or to take arms against a sea of troubles, And by opposing end them? To die: to sleep; No more; and by a sleep to say we end The heart-ache and the thousand natural shocks That flesh is heir to, 'tis a consummation Devoutly to be wish'd. To die, to sleep; To sleep: perchance to dream: ay, there's the rub; For in that sleep of death what dreams may come When we have shuffled off this mortal coil, Must give us pause: there's the respect That makes calamity of so long life; For who would bear the whips and scorns of time, The oppressor's wrong, the proud man's contumely, The pangs of despised love, the law's delay, The insolence of office and the spurns That patient merit of the unworthy takes, When he himself might his quietus make With a bare bodkin? who would fardels bear, To grunt and sweat under a weary life, But that the dread of something after death, The undiscover'd country from whose bourn No traveller returns, puzzles the will And makes us rather bear those ills we have Than fly to others that we know not of? Thus conscience does make cowards of us all; And thus the native hue of resolution Is sicklied o'er with the pale cast of thought, And enterprises of great pith and moment With this regard their currents turn awry, And lose the name of action.--Soft you now! The fair Ophelia! Nymph, in thy orisons Be all my sins remember'd. OPHELIA Good my lord, How does your honour for this many a day? HAMLET I humbly thank you; well, well, well. OPHELIA My lord, I have remembrances of yours, That I have longed long to re-deliver; I pray you, now receive them. HAMLET No, not I; I never gave you aught. OPHELIA My honour'd lord, you know right well you did; And, with them, words of so sweet breath composed As made the things more rich: their perfume lost, Take these again; for to the noble mind Rich gifts wax poor when givers prove unkind. There, my lord. HAMLET Ha, ha! are you honest? OPHELIA My lord? HAMLET Are you fair? OPHELIA What means your lordship? HAMLET That if you be honest and fair, your honesty should admit no discourse to your beauty. OPHELIA Could beauty, my lord, have better commerce than with honesty? HAMLET Ay, truly; for the power of beauty will sooner transform honesty from what it is to a bawd than the force of honesty can translate beauty into his likeness: this was sometime a paradox, but now the time gives it proof. I did love you once. OPHELIA Indeed, my lord, you made me believe so. HAMLET You should not have believed me; for virtue cannot so inoculate our old stock but we shall relish of it: I loved you not. OPHELIA I was the more deceived. HAMLET Get thee to a nunnery: why wouldst thou be a breeder of sinners? I am myself indifferent honest; but yet I could accuse me of such things that it were better my mother had not borne me: I am very proud, revengeful, ambitious, with more offences at my beck than I have thoughts to put them in, imagination to give them shape, or time to act them in. What should such fellows as I do crawling between earth and heaven? We are arrant knaves, all; believe none of us. Go thy ways to a nunnery. Where's your father? OPHELIA At home, my lord. HAMLET Let the doors be shut upon him, that he may play the fool no where but in's own house. Farewell. OPHELIA O, help him, you sweet heavens! HAMLET If thou dost marry, I'll give thee this plague for thy dowry: be thou as chaste as ice, as pure as snow, thou shalt not escape calumny. Get thee to a nunnery, go: farewell. Or, if thou wilt needs marry, marry a fool; for wise men know well enough what monsters you make of them. To a nunnery, go, and quickly too. Farewell. OPHELIA O heavenly powers, restore him! HAMLET I have heard of your paintings too, well enough; God has given you one face, and you make yourselves another: you jig, you amble, and you lisp, and nick-name God's creatures, and make your wantonness your ignorance. Go to, I'll no more on't; it hath made me mad. I say, we will have no more marriages: those that are married already, all but one, shall live; the rest shall keep as they are. To a nunnery, go. Exit OPHELIA O, what a noble mind is here o'erthrown! The courtier's, soldier's, scholar's, eye, tongue, sword; The expectancy and rose of the fair state, The glass of fashion and the mould of form, The observed of all observers, quite, quite down! And I, of ladies most deject and wretched, That suck'd the honey of his music vows, Now see that noble and most sovereign reason, Like sweet bells jangled, out of tune and harsh; That unmatch'd form and feature of blown youth Blasted with ecstasy: O, woe is me, To have seen what I have seen, see what I see! Re-enter KING CLAUDIUS and POLONIUS KING CLAUDIUS Love! his affections do not that way tend; Nor what he spake, though it lack'd form a little, Was not like madness. There's something in his soul, O'er which his melancholy sits on brood; And I do doubt the hatch and the disclose Will be some danger: which for to prevent, I have in quick determination Thus set it down: he shall with speed to England, For the demand of our neglected tribute Haply the seas and countries different With variable objects shall expel This something-settled matter in his heart, Whereon his brains still beating puts him thus From fashion of himself. What think you on't? LORD POLONIUS It shall do well: but yet do I believe The origin and commencement of his grief Sprung from neglected love. How now, Ophelia! You need not tell us what Lord Hamlet said; We heard it all. My lord, do as you please; But, if you hold it fit, after the play Let his queen mother all alone entreat him To show his grief: let her be round with him; And I'll be placed, so please you, in the ear Of all their conference. If she find him not, To England send him, or confine him where Your wisdom best shall think. KING CLAUDIUS It shall be so: Madness in great ones must not unwatch'd go. Exeunt SCENE II. A hall in the castle. Enter HAMLET and Players HAMLET Speak the speech, I pray you, as I pronounced it to you, trippingly on the tongue: but if you mouth it, as many of your players do, I had as lief the town-crier spoke my lines. Nor do not saw the air too much with your hand, thus, but use all gently; for in the very torrent, tempest, and, as I may say, the whirlwind of passion, you must acquire and beget a temperance that may give it smoothness. O, it offends me to the soul to hear a robustious periwig-pated fellow tear a passion to tatters, to very rags, to split the ears of the groundlings, who for the most part are capable of nothing but inexplicable dumbshows and noise: I would have such a fellow whipped for o'erdoing Termagant; it out-herods Herod: pray you, avoid it. First Player I warrant your honour. HAMLET Be not too tame neither, but let your own discretion be your tutor: suit the action to the word, the word to the action; with this special o'erstep not the modesty of nature: for any thing so overdone is from the purpose of playing, whose end, both at the first and now, was and is, to hold, as 'twere, the mirror up to nature; to show virtue her own feature, scorn her own image, and the very age and body of the time his form and pressure. Now this overdone, or come tardy off, though it make the unskilful laugh, cannot but make the judicious grieve; the censure of the which one must in your allowance o'erweigh a whole theatre of others. O, there be players that I have seen play, and heard others praise, and that highly, not to speak it profanely, that, neither having the accent of Christians nor the gait of Christian, pagan, nor man, have so strutted and bellowed that I have thought some of nature's journeymen had made men and not made them well, they imitated humanity so abominably. First Player I hope we have reformed that indifferently with us, sir. HAMLET O, reform it altogether. And let those that play your clowns speak no more than is set down for them; for there be of them that will themselves laugh, to set on some quantity of barren spectators to laugh too; though, in the mean time, some necessary question of the play be then to be considered: that's villanous, and shows a most pitiful ambition in the fool that uses it. Go, make you ready. Exeunt Players Enter POLONIUS, ROSENCRANTZ, and GUILDENSTERN How now, my lord! I will the king hear this piece of work? LORD POLONIUS And the queen too, and that presently. HAMLET Bid the players make haste. Exit POLONIUS Will you two help to hasten them? ROSENCRANTZ GUILDENSTERN We will, my lord. Exeunt ROSENCRANTZ and GUILDENSTERN HAMLET What ho! Horatio! Enter HORATIO HORATIO Here, sweet lord, at your service. HAMLET Horatio, thou art e'en as just a man As e'er my conversation coped withal. HORATIO O, my dear lord,-- HAMLET Nay, do not think I flatter; For what advancement may I hope from thee That no revenue hast but thy good spirits, To feed and clothe thee? Why should the poor be flatter'd? No, let the candied tongue lick absurd pomp, And crook the pregnant hinges of the knee Where thrift may follow fawning. Dost thou hear? Since my dear soul was mistress of her choice And could of men distinguish, her election Hath seal'd thee for herself; for thou hast been As one, in suffering all, that suffers nothing, A man that fortune's buffets and rewards Hast ta'en with equal thanks: and blest are those Whose blood and judgment are so well commingled, That they are not a pipe for fortune's finger To sound what stop she please. Give me that man That is not passion's slave, and I will wear him In my heart's core, ay, in my heart of heart, As I do thee.--Something too much of this.-- There is a play to-night before the king; One scene of it comes near the circumstance Which I have told thee of my father's death: I prithee, when thou seest that act afoot, Even with the very comment of thy soul Observe mine uncle: if his occulted guilt Do not itself unkennel in one speech, It is a damned ghost that we have seen, And my imaginations are as foul As Vulcan's stithy. Give him heedful note; For I mine eyes will rivet to his face, And after we will both our judgments join In censure of his seeming. HORATIO Well, my lord: If he steal aught the whilst this play is playing, And 'scape detecting, I will pay the theft. HAMLET They are coming to the play; I must be idle: Get you a place. Danish march. A flourish. Enter KING CLAUDIUS, QUEEN GERTRUDE, POLONIUS, OPHELIA, ROSENCRANTZ, GUILDENSTERN, and others KING CLAUDIUS How fares our cousin Hamlet? HAMLET Excellent, i' faith; of the chameleon's dish: I eat the air, promise-crammed: you cannot feed capons so. KING CLAUDIUS I have nothing with this answer, Hamlet; these words are not mine. HAMLET No, nor mine now. To POLONIUS My lord, you played once i' the university, you say? LORD POLONIUS That did I, my lord; and was accounted a good actor. HAMLET What did you enact? LORD POLONIUS I did enact Julius Caesar: I was killed i' the Capitol; Brutus killed me. HAMLET It was a brute part of him to kill so capital a calf there. Be the players ready? ROSENCRANTZ Ay, my lord; they stay upon your patience. QUEEN GERTRUDE Come hither, my dear Hamlet, sit by me. HAMLET No, good mother, here's metal more attractive. LORD POLONIUS To KING CLAUDIUS O, ho! do you mark that? HAMLET Lady, shall I lie in your lap? Lying down at OPHELIA's feet OPHELIA No, my lord. HAMLET I mean, my head upon your lap? OPHELIA Ay, my lord. HAMLET Do you think I meant country matters? OPHELIA I think nothing, my lord. HAMLET That's a fair thought to lie between maids' legs. OPHELIA What is, my lord? HAMLET Nothing. OPHELIA You are merry, my lord. HAMLET Who, I? OPHELIA Ay, my lord. HAMLET O God, your only jig-maker. What should a man do but be merry? for, look you, how cheerfully my mother looks, and my father died within these two hours. OPHELIA Nay, 'tis twice two months, my lord. HAMLET So long? Nay then, let the devil wear black, for I'll have a suit of sables. O heavens! die two months ago, and not forgotten yet? Then there's hope a great man's memory may outlive his life half a year: but, by'r lady, he must build churches, then; or else shall he suffer not thinking on, with the hobby-horse, whose epitaph is 'For, O, for, O, the hobby-horse is forgot.' Hautboys play. The dumb-show enters Enter a King and a Queen very lovingly; the Queen embracing him, and he her. She kneels, and makes show of protestation unto him. He takes her up, and declines his head upon her neck: lays him down upon a bank of flowers: she, seeing him asleep, leaves him. Anon comes in a fellow, takes off his crown, kisses it, and pours poison in the King's ears, and exit. The Queen returns; finds the King dead, and makes passionate action. The Poisoner, with some two or three Mutes, comes in again, seeming to lament with her. The dead body is carried away. The Poisoner wooes the Queen with gifts: she seems loath and unwilling awhile, but in the end accepts his love Exeunt OPHELIA What means this, my lord? HAMLET Marry, this is miching mallecho; it means mischief. OPHELIA Belike this show imports the argument of the play. Enter Prologue HAMLET We shall know by this fellow: the players cannot keep counsel; they'll tell all. OPHELIA Will he tell us what this show meant? HAMLET Ay, or any show that you'll show him: be not you ashamed to show, he'll not shame to tell you what it means. OPHELIA You are naught, you are naught: I'll mark the play. Prologue For us, and for our tragedy, Here stooping to your clemency, We beg your hearing patiently. Exit HAMLET Is this a prologue, or the posy of a ring? OPHELIA 'Tis brief, my lord. HAMLET As woman's love. Enter two Players, King and Queen Player King Full thirty times hath Phoebus' cart gone round Neptune's salt wash and Tellus' orbed ground, And thirty dozen moons with borrow'd sheen About the world have times twelve thirties been, Since love our hearts and Hymen did our hands Unite commutual in most sacred bands. Player Queen So many journeys may the sun and moon Make us again count o'er ere love be done! But, woe is me, you are so sick of late, So far from cheer and from your former state, That I distrust you. Yet, though I distrust, Discomfort you, my lord, it nothing must: For women's fear and love holds quantity; In neither aught, or in extremity. Now, what my love is, proof hath made you know; And as my love is sized, my fear is so: Where love is great, the littlest doubts are fear; Where little fears grow great, great love grows there. Player King 'Faith, I must leave thee, love, and shortly too; My operant powers their functions leave to do: And thou shalt live in this fair world behind, Honour'd, beloved; and haply one as kind For husband shalt thou-- Player Queen O, confound the rest! Such love must needs be treason in my breast: In second husband let me be accurst! None wed the second but who kill'd the first. HAMLET Aside Wormwood, wormwood. Player Queen The instances that second marriage move Are base respects of thrift, but none of love: A second time I kill my husband dead, When second husband kisses me in bed. Player King I do believe you think what now you speak; But what we do determine oft we break. Purpose is but the slave to memory, Of violent birth, but poor validity; Which now, like fruit unripe, sticks on the tree; But fall, unshaken, when they mellow be. Most necessary 'tis that we forget To pay ourselves what to ourselves is debt: What to ourselves in passion we propose, The passion ending, doth the purpose lose. The violence of either grief or joy Their own enactures with themselves destroy: Where joy most revels, grief doth most lament; Grief joys, joy grieves, on slender accident. This world is not for aye, nor 'tis not strange That even our loves should with our fortunes change; For 'tis a question left us yet to prove, Whether love lead fortune, or else fortune love. The great man down, you mark his favourite flies; The poor advanced makes friends of enemies. And hitherto doth love on fortune tend; For who not needs shall never lack a friend, And who in want a hollow friend doth try, Directly seasons him his enemy. But, orderly to end where I begun, Our wills and fates do so contrary run That our devices still are overthrown; Our thoughts are ours, their ends none of our own: So think thou wilt no second husband wed; But die thy thoughts when thy first lord is dead. Player Queen Nor earth to me give food, nor heaven light! Sport and repose lock from me day and night! To desperation turn my trust and hope! An anchor's cheer in prison be my scope! Each opposite that blanks the face of joy Meet what I would have well and it destroy! Both here and hence pursue me lasting strife, If, once a widow, ever I be wife! HAMLET If she should break it now! Player King 'Tis deeply sworn. Sweet, leave me here awhile; My spirits grow dull, and fain I would beguile The tedious day with sleep. Sleeps Player Queen Sleep rock thy brain, And never come mischance between us twain! Exit HAMLET Madam, how like you this play? QUEEN GERTRUDE The lady protests too much, methinks. HAMLET O, but she'll keep her word. KING CLAUDIUS Have you heard the argument? Is there no offence in 't? HAMLET No, no, they do but jest, poison in jest; no offence i' the world. KING CLAUDIUS What do you call the play? HAMLET The Mouse-trap. Marry, how? Tropically. This play is the image of a murder done in Vienna: Gonzago is the duke's name; his wife, Baptista: you shall see anon; 'tis a knavish piece of work: but what o' that? your majesty and we that have free souls, it touches us not: let the galled jade wince, our withers are unwrung. Enter LUCIANUS This is one Lucianus, nephew to the king. OPHELIA You are as good as a chorus, my lord. HAMLET I could interpret between you and your love, if I could see the puppets dallying. OPHELIA You are keen, my lord, you are keen. HAMLET It would cost you a groaning to take off my edge. OPHELIA Still better, and worse. HAMLET So you must take your husbands. Begin, murderer; pox, leave thy damnable faces, and begin. Come: 'the croaking raven doth bellow for revenge.' LUCIANUS Thoughts black, hands apt, drugs fit, and time agreeing; Confederate season, else no creature seeing; Thou mixture rank, of midnight weeds collected, With Hecate's ban thrice blasted, thrice infected, Thy natural magic and dire property, On wholesome life usurp immediately. Pours the poison into the sleeper's ears HAMLET He poisons him i' the garden for's estate. His name's Gonzago: the story is extant, and writ in choice Italian: you shall see anon how the murderer gets the love of Gonzago's wife. OPHELIA The king rises. HAMLET What, frighted with false fire! QUEEN GERTRUDE How fares my lord? LORD POLONIUS Give o'er the play. KING CLAUDIUS Give me some light: away! All Lights, lights, lights! Exeunt all but HAMLET and HORATIO HAMLET Why, let the stricken deer go weep, The hart ungalled play; For some must watch, while some must sleep: So runs the world away. Would not this, sir, and a forest of feathers-- if the rest of my fortunes turn Turk with me--with two Provincial roses on my razed shoes, get me a fellowship in a cry of players, sir? HORATIO Half a share. HAMLET A whole one, I. For thou dost know, O Damon dear, This realm dismantled was Of Jove himself; and now reigns here A very, very--pajock. HORATIO You might have rhymed. HAMLET O good Horatio, I'll take the ghost's word for a thousand pound. Didst perceive? HORATIO Very well, my lord. HAMLET Upon the talk of the poisoning? HORATIO I did very well note him. HAMLET Ah, ha! Come, some music! come, the recorders! For if the king like not the comedy, Why then, belike, he likes it not, perdy. Come, some music! Re-enter ROSENCRANTZ and GUILDENSTERN GUILDENSTERN Good my lord, vouchsafe me a word with you. HAMLET Sir, a whole history. GUILDENSTERN The king, sir,-- HAMLET Ay, sir, what of him? GUILDENSTERN Is in his retirement marvellous distempered. HAMLET With drink, sir? GUILDENSTERN No, my lord, rather with choler. HAMLET Your wisdom should show itself more richer to signify this to his doctor; for, for me to put him to his purgation would perhaps plunge him into far more choler. GUILDENSTERN Good my lord, put your discourse into some frame and start not so wildly from my affair. HAMLET I am tame, sir: pronounce. GUILDENSTERN The queen, your mother, in most great affliction of spirit, hath sent me to you. HAMLET You are welcome. GUILDENSTERN Nay, good my lord, this courtesy is not of the right breed. If it shall please you to make me a wholesome answer, I will do your mother's commandment: if not, your pardon and my return shall be the end of my business. HAMLET Sir, I cannot. GUILDENSTERN What, my lord? HAMLET Make you a wholesome answer; my wit's diseased: but, sir, such answer as I can make, you shall command; or, rather, as you say, my mother: therefore no more, but to the matter: my mother, you say,-- ROSENCRANTZ Then thus she says; your behavior hath struck her into amazement and admiration. HAMLET O wonderful son, that can so astonish a mother! But is there no sequel at the heels of this mother's admiration? Impart. ROSENCRANTZ She desires to speak with you in her closet, ere you go to bed. HAMLET We shall obey, were she ten times our mother. Have you any further trade with us? ROSENCRANTZ My lord, you once did love me. HAMLET So I do still, by these pickers and stealers. ROSENCRANTZ Good my lord, what is your cause of distemper? you do, surely, bar the door upon your own liberty, if you deny your griefs to your friend. HAMLET Sir, I lack advancement. ROSENCRANTZ How can that be, when you have the voice of the king himself for your succession in Denmark? HAMLET Ay, but sir, 'While the grass grows,'--the proverb is something musty. Re-enter Players with recorders O, the recorders! let me see one. To withdraw with you:--why do you go about to recover the wind of me, as if you would drive me into a toil? GUILDENSTERN O, my lord, if my duty be too bold, my love is too unmannerly. HAMLET I do not well understand that. Will you play upon this pipe? GUILDENSTERN My lord, I cannot. HAMLET I pray you. GUILDENSTERN Believe me, I cannot. HAMLET I do beseech you. GUILDENSTERN I know no touch of it, my lord. HAMLET 'Tis as easy as lying: govern these ventages with your lingers and thumb, give it breath with your mouth, and it will discourse most eloquent music. Look you, these are the stops. GUILDENSTERN But these cannot I command to any utterance of harmony; I have not the skill. HAMLET Why, look you now, how unworthy a thing you make of me! You would play upon me; you would seem to know my stops; you would pluck out the heart of my mystery; you would sound me from my lowest note to the top of my compass: and there is much music, excellent voice, in this little organ; yet cannot you make it speak. 'Sblood, do you think I am easier to be played on than a pipe? Call me what instrument you will, though you can fret me, yet you cannot play upon me. Enter POLONIUS God bless you, sir! LORD POLONIUS My lord, the queen would speak with you, and presently. HAMLET Do you see yonder cloud that's almost in shape of a camel? LORD POLONIUS By the mass, and 'tis like a camel, indeed. HAMLET Methinks it is like a weasel. LORD POLONIUS It is backed like a weasel. HAMLET Or like a whale? LORD POLONIUS Very like a whale. HAMLET Then I will come to my mother by and by. They fool me to the top of my bent. I will come by and by. LORD POLONIUS I will say so. HAMLET By and by is easily said. Exit POLONIUS Leave me, friends. Exeunt all but HAMLET Tis now the very witching time of night, When churchyards yawn and hell itself breathes out Contagion to this world: now could I drink hot blood, And do such bitter business as the day Would quake to look on. Soft! now to my mother. O heart, lose not thy nature; let not ever The soul of Nero enter this firm bosom: Let me be cruel, not unnatural: I will speak daggers to her, but use none; My tongue and soul in this be hypocrites; How in my words soever she be shent, To give them seals never, my soul, consent! Exit SCENE III. A room in the castle. Enter KING CLAUDIUS, ROSENCRANTZ, and GUILDENSTERN KING CLAUDIUS I like him not, nor stands it safe with us To let his madness range. Therefore prepare you; I your commission will forthwith dispatch, And he to England shall along with you: The terms of our estate may not endure Hazard so dangerous as doth hourly grow Out of his lunacies. GUILDENSTERN We will ourselves provide: Most holy and religious fear it is To keep those many many bodies safe That live and feed upon your majesty. ROSENCRANTZ The single and peculiar life is bound, With all the strength and armour of the mind, To keep itself from noyance; but much more That spirit upon whose weal depend and rest The lives of many. The cease of majesty Dies not alone; but, like a gulf, doth draw What's near it with it: it is a massy wheel, Fix'd on the summit of the highest mount, To whose huge spokes ten thousand lesser things Are mortised and adjoin'd; which, when it falls, Each small annexment, petty consequence, Attends the boisterous ruin. Never alone Did the king sigh, but with a general groan. KING CLAUDIUS Arm you, I pray you, to this speedy voyage; For we will fetters put upon this fear, Which now goes too free-footed. ROSENCRANTZ GUILDENSTERN We will haste us. Exeunt ROSENCRANTZ and GUILDENSTERN Enter POLONIUS LORD POLONIUS My lord, he's going to his mother's closet: Behind the arras I'll convey myself, To hear the process; and warrant she'll tax him home: And, as you said, and wisely was it said, 'Tis meet that some more audience than a mother, Since nature makes them partial, should o'erhear The speech, of vantage. Fare you well, my liege: I'll call upon you ere you go to bed, And tell you what I know. KING CLAUDIUS Thanks, dear my lord. Exit POLONIUS O, my offence is rank it smells to heaven; It hath the primal eldest curse upon't, A brother's murder. Pray can I not, Though inclination be as sharp as will: My stronger guilt defeats my strong intent; And, like a man to double business bound, I stand in pause where I shall first begin, And both neglect. What if this cursed hand Were thicker than itself with brother's blood, Is there not rain enough in the sweet heavens To wash it white as snow? Whereto serves mercy But to confront the visage of offence? And what's in prayer but this two-fold force, To be forestalled ere we come to fall, Or pardon'd being down? Then I'll look up; My fault is past. But, O, what form of prayer Can serve my turn? 'Forgive me my foul murder'? That cannot be; since I am still possess'd Of those effects for which I did the murder, My crown, mine own ambition and my queen. May one be pardon'd and retain the offence? In the corrupted currents of this world Offence's gilded hand may shove by justice, And oft 'tis seen the wicked prize itself Buys out the law: but 'tis not so above; There is no shuffling, there the action lies In his true nature; and we ourselves compell'd, Even to the teeth and forehead of our faults, To give in evidence. What then? what rests? Try what repentance can: what can it not? Yet what can it when one can not repent? O wretched state! O bosom black as death! O limed soul, that, struggling to be free, Art more engaged! Help, angels! Make assay! Bow, stubborn knees; and, heart with strings of steel, Be soft as sinews of the newborn babe! All may be well. Retires and kneels Enter HAMLET HAMLET Now might I do it pat, now he is praying; And now I'll do't. And so he goes to heaven; And so am I revenged. That would be scann'd: A villain kills my father; and for that, I, his sole son, do this same villain send To heaven. O, this is hire and salary, not revenge. He took my father grossly, full of bread; With all his crimes broad blown, as flush as May; And how his audit stands who knows save heaven? But in our circumstance and course of thought, 'Tis heavy with him: and am I then revenged, To take him in the purging of his soul, When he is fit and season'd for his passage? No! Up, sword; and know thou a more horrid hent: When he is drunk asleep, or in his rage, Or in the incestuous pleasure of his bed; At gaming, swearing, or about some act That has no relish of salvation in't; Then trip him, that his heels may kick at heaven, And that his soul may be as damn'd and black As hell, whereto it goes. My mother stays: This physic but prolongs thy sickly days. Exit KING CLAUDIUS Rising My words fly up, my thoughts remain below: Words without thoughts never to heaven go. Exit SCENE IV. The Queen's closet. Enter QUEEN MARGARET and POLONIUS LORD POLONIUS He will come straight. Look you lay home to him: Tell him his pranks have been too broad to bear with, And that your grace hath screen'd and stood between Much heat and him. I'll sconce me even here. Pray you, be round with him. HAMLET Within Mother, mother, mother! QUEEN GERTRUDE I'll warrant you, Fear me not: withdraw, I hear him coming. POLONIUS hides behind the arras Enter HAMLET HAMLET Now, mother, what's the matter? QUEEN GERTRUDE Hamlet, thou hast thy father much offended. HAMLET Mother, you have my father much offended. QUEEN GERTRUDE Come, come, you answer with an idle tongue. HAMLET Go, go, you question with a wicked tongue. QUEEN GERTRUDE Why, how now, Hamlet! HAMLET What's the matter now? QUEEN GERTRUDE Have you forgot me? HAMLET No, by the rood, not so: You are the queen, your husband's brother's wife; And--would it were not so!--you are my mother. QUEEN GERTRUDE Nay, then, I'll set those to you that can speak. HAMLET Come, come, and sit you down; you shall not budge; You go not till I set you up a glass Where you may see the inmost part of you. QUEEN GERTRUDE What wilt thou do? thou wilt not murder me? Help, help, ho! LORD POLONIUS Behind What, ho! help, help, help! HAMLET Drawing How now! a rat? Dead, for a ducat, dead! Makes a pass through the arras LORD POLONIUS Behind O, I am slain! Falls and dies QUEEN GERTRUDE O me, what hast thou done? HAMLET Nay, I know not: Is it the king? QUEEN GERTRUDE O, what a rash and bloody deed is this! HAMLET A bloody deed! almost as bad, good mother, As kill a king, and marry with his brother. QUEEN GERTRUDE As kill a king! HAMLET Ay, lady, 'twas my word. Lifts up the array and discovers POLONIUS Thou wretched, rash, intruding fool, farewell! I took thee for thy better: take thy fortune; Thou find'st to be too busy is some danger. Leave wringing of your hands: peace! sit you down, And let me wring your heart; for so I shall, If it be made of penetrable stuff, If damned custom have not brass'd it so That it is proof and bulwark against sense. QUEEN GERTRUDE What have I done, that thou darest wag thy tongue In noise so rude against me? HAMLET Such an act That blurs the grace and blush of modesty, Calls virtue hypocrite, takes off the rose From the fair forehead of an innocent love And sets a blister there, makes marriage-vows As false as dicers' oaths: O, such a deed As from the body of contraction plucks The very soul, and sweet religion makes A rhapsody of words: heaven's face doth glow: Yea, this solidity and compound mass, With tristful visage, as against the doom, Is thought-sick at the act. QUEEN GERTRUDE Ay me, what act, That roars so loud, and thunders in the index? HAMLET Look here, upon this picture, and on this, The counterfeit presentment of two brothers. See, what a grace was seated on this brow; Hyperion's curls; the front of Jove himself; An eye like Mars, to threaten and command; A station like the herald Mercury New-lighted on a heaven-kissing hill; A combination and a form indeed, Where every god did seem to set his seal, To give the world assurance of a man: This was your husband. Look you now, what follows: Here is your husband; like a mildew'd ear, Blasting his wholesome brother. Have you eyes? Could you on this fair mountain leave to feed, And batten on this moor? Ha! have you eyes? You cannot call it love; for at your age The hey-day in the blood is tame, it's humble, And waits upon the judgment: and what judgment Would step from this to this? Sense, sure, you have, Else could you not have motion; but sure, that sense Is apoplex'd; for madness would not err, Nor sense to ecstasy was ne'er so thrall'd But it reserved some quantity of choice, To serve in such a difference. What devil was't That thus hath cozen'd you at hoodman-blind? Eyes without feeling, feeling without sight, Ears without hands or eyes, smelling sans all, Or but a sickly part of one true sense Could not so mope. O shame! where is thy blush? Rebellious hell, If thou canst mutine in a matron's bones, To flaming youth let virtue be as wax, And melt in her own fire: proclaim no shame When the compulsive ardour gives the charge, Since frost itself as actively doth burn And reason panders will. QUEEN GERTRUDE O Hamlet, speak no more: Thou turn'st mine eyes into my very soul; And there I see such black and grained spots As will not leave their tinct. HAMLET Nay, but to live In the rank sweat of an enseamed bed, Stew'd in corruption, honeying and making love Over the nasty sty,-- QUEEN GERTRUDE O, speak to me no more; These words, like daggers, enter in mine ears; No more, sweet Hamlet! HAMLET A murderer and a villain; A slave that is not twentieth part the tithe Of your precedent lord; a vice of kings; A cutpurse of the empire and the rule, That from a shelf the precious diadem stole, And put it in his pocket! QUEEN GERTRUDE No more! HAMLET A king of shreds and patches,-- Enter Ghost Save me, and hover o'er me with your wings, You heavenly guards! What would your gracious figure? QUEEN GERTRUDE Alas, he's mad! HAMLET Do you not come your tardy son to chide, That, lapsed in time and passion, lets go by The important acting of your dread command? O, say! Ghost Do not forget: this visitation Is but to whet thy almost blunted purpose. But, look, amazement on thy mother sits: O, step between her and her fighting soul: Conceit in weakest bodies strongest works: Speak to her, Hamlet. HAMLET How is it with you, lady? QUEEN GERTRUDE Alas, how is't with you, That you do bend your eye on vacancy And with the incorporal air do hold discourse? Forth at your eyes your spirits wildly peep; And, as the sleeping soldiers in the alarm, Your bedded hair, like life in excrements, Starts up, and stands on end. O gentle son, Upon the heat and flame of thy distemper Sprinkle cool patience. Whereon do you look? HAMLET On him, on him! Look you, how pale he glares! His form and cause conjoin'd, preaching to stones, Would make them capable. Do not look upon me; Lest with this piteous action you convert My stern effects: then what I have to do Will want true colour; tears perchance for blood. QUEEN GERTRUDE To whom do you speak this? HAMLET Do you see nothing there? QUEEN GERTRUDE Nothing at all; yet all that is I see. HAMLET Nor did you nothing hear? QUEEN GERTRUDE No, nothing but ourselves. HAMLET Why, look you there! look, how it steals away! My father, in his habit as he lived! Look, where he goes, even now, out at the portal! Exit Ghost QUEEN GERTRUDE This the very coinage of your brain: This bodiless creation ecstasy Is very cunning in. HAMLET Ecstasy! My pulse, as yours, doth temperately keep time, And makes as healthful music: it is not madness That I have utter'd: bring me to the test, And I the matter will re-word; which madness Would gambol from. Mother, for love of grace, Lay not that mattering unction to your soul, That not your trespass, but my madness speaks: It will but skin and film the ulcerous place, Whilst rank corruption, mining all within, Infects unseen. Confess yourself to heaven; Repent what's past; avoid what is to come; And do not spread the compost on the weeds, To make them ranker. Forgive me this my virtue; For in the fatness of these pursy times Virtue itself of vice must pardon beg, Yea, curb and woo for leave to do him good. QUEEN GERTRUDE O Hamlet, thou hast cleft my heart in twain. HAMLET O, throw away the worser part of it, And live the purer with the other half. Good night: but go not to mine uncle's bed; Assume a virtue, if you have it not. That monster, custom, who all sense doth eat, Of habits devil, is angel yet in this, That to the use of actions fair and good He likewise gives a frock or livery, That aptly is put on. Refrain to-night, And that shall lend a kind of easiness To the next abstinence: the next more easy; For use almost can change the stamp of nature, And either ... the devil, or throw him out With wondrous potency. Once more, good night: And when you are desirous to be bless'd, I'll blessing beg of you. For this same lord, Pointing to POLONIUS I do repent: but heaven hath pleased it so, To punish me with this and this with me, That I must be their scourge and minister. I will bestow him, and will answer well The death I gave him. So, again, good night. I must be cruel, only to be kind: Thus bad begins and worse remains behind. One word more, good lady. QUEEN GERTRUDE What shall I do? HAMLET Not this, by no means, that I bid you do: Let the bloat king tempt you again to bed; Pinch wanton on your cheek; call you his mouse; And let him, for a pair of reechy kisses, Or paddling in your neck with his damn'd fingers, Make you to ravel all this matter out, That I essentially am not in madness, But mad in craft. 'Twere good you let him know; For who, that's but a queen, fair, sober, wise, Would from a paddock, from a bat, a gib, Such dear concernings hide? who would do so? No, in despite of sense and secrecy, Unpeg the basket on the house's top. Let the birds fly, and, like the famous ape, To try conclusions, in the basket creep, And break your own neck down. QUEEN GERTRUDE Be thou assured, if words be made of breath, And breath of life, I have no life to breathe What thou hast said to me. HAMLET I must to England; you know that? QUEEN GERTRUDE Alack, I had forgot: 'tis so concluded on. HAMLET There's letters seal'd: and my two schoolfellows, Whom I will trust as I will adders fang'd, They bear the mandate; they must sweep my way, And marshal me to knavery. Let it work; For 'tis the sport to have the engineer Hoist with his own petard: and 't shall go hard But I will delve one yard below their mines, And blow them at the moon: O, 'tis most sweet, When in one line two crafts directly meet. This man shall set me packing: I'll lug the guts into the neighbour room. Mother, good night. Indeed this counsellor Is now most still, most secret and most grave, Who was in life a foolish prating knave. Come, sir, to draw toward an end with you. Good night, mother. Exeunt severally; HAMLET dragging in POLONIUS ACT IV SCENE I. A room in the castle. Enter KING CLAUDIUS, QUEEN GERTRUDE, ROSENCRANTZ, and GUILDENSTERN KING CLAUDIUS There's matter in these sighs, these profound heaves: You must translate: 'tis fit we understand them. Where is your son? QUEEN GERTRUDE Bestow this place on us a little while. Exeunt ROSENCRANTZ and GUILDENSTERN Ah, my good lord, what have I seen to-night! KING CLAUDIUS What, Gertrude? How does Hamlet? QUEEN GERTRUDE Mad as the sea and wind, when both contend Which is the mightier: in his lawless fit, Behind the arras hearing something stir, Whips out his rapier, cries, 'A rat, a rat!' And, in this brainish apprehension, kills The unseen good old man. KING CLAUDIUS O heavy deed! It had been so with us, had we been there: His liberty is full of threats to all; To you yourself, to us, to every one. Alas, how shall this bloody deed be answer'd? It will be laid to us, whose providence Should have kept short, restrain'd and out of haunt, This mad young man: but so much was our love, We would not understand what was most fit; But, like the owner of a foul disease, To keep it from divulging, let it feed Even on the pith of Life. Where is he gone? QUEEN GERTRUDE To draw apart the body he hath kill'd: O'er whom his very madness, like some ore Among a mineral of metals base, Shows itself pure; he weeps for what is done. KING CLAUDIUS O Gertrude, come away! The sun no sooner shall the mountains touch, But we will ship him hence: and this vile deed We must, with all our majesty and skill, Both countenance and excuse. Ho, Guildenstern! Re-enter ROSENCRANTZ and GUILDENSTERN Friends both, go join you with some further aid: Hamlet in madness hath Polonius slain, And from his mother's closet hath he dragg'd him: Go seek him out; speak fair, and bring the body Into the chapel. I pray you, haste in this. Exeunt ROSENCRANTZ and GUILDENSTERN Come, Gertrude, we'll call up our wisest friends; And let them know, both what we mean to do, And what's untimely done... Whose whisper o'er the world's diameter, As level as the cannon to his blank, Transports his poison'd shot, may miss our name, And hit the woundless air. O, come away! My soul is full of discord and dismay. Exeunt SCENE II. Another room in the castle. Enter HAMLET HAMLET Safely stowed. ROSENCRANTZ GUILDENSTERN Within Hamlet! Lord Hamlet! HAMLET What noise? who calls on Hamlet? O, here they come. Enter ROSENCRANTZ and GUILDENSTERN ROSENCRANTZ What have you done, my lord, with the dead body? HAMLET Compounded it with dust, whereto 'tis kin. ROSENCRANTZ Tell us where 'tis, that we may take it thence And bear it to the chapel. HAMLET Do not believe it. ROSENCRANTZ Believe what? HAMLET That I can keep your counsel and not mine own. Besides, to be demanded of a sponge! what replication should be made by the son of a king? ROSENCRANTZ Take you me for a sponge, my lord? HAMLET Ay, sir, that soaks up the king's countenance, his rewards, his authorities. But such officers do the king best service in the end: he keeps them, like an ape, in the corner of his jaw; first mouthed, to be last swallowed: when he needs what you have gleaned, it is but squeezing you, and, sponge, you shall be dry again. ROSENCRANTZ I understand you not, my lord. HAMLET I am glad of it: a knavish speech sleeps in a foolish ear. ROSENCRANTZ My lord, you must tell us where the body is, and go with us to the king. HAMLET The body is with the king, but the king is not with the body. The king is a thing-- GUILDENSTERN A thing, my lord! HAMLET Of nothing: bring me to him. Hide fox, and all after. Exeunt SCENE III. Another room in the castle. Enter KING CLAUDIUS, attended KING CLAUDIUS I have sent to seek him, and to find the body. How dangerous is it that this man goes loose! Yet must not we put the strong law on him: He's loved of the distracted multitude, Who like not in their judgment, but their eyes; And where tis so, the offender's scourge is weigh'd, But never the offence. To bear all smooth and even, This sudden sending him away must seem Deliberate pause: diseases desperate grown By desperate appliance are relieved, Or not at all. Enter ROSENCRANTZ How now! what hath befall'n? ROSENCRANTZ Where the dead body is bestow'd, my lord, We cannot get from him. KING CLAUDIUS But where is he? ROSENCRANTZ Without, my lord; guarded, to know your pleasure. KING CLAUDIUS Bring him before us. ROSENCRANTZ Ho, Guildenstern! bring in my lord. Enter HAMLET and GUILDENSTERN KING CLAUDIUS Now, Hamlet, where's Polonius? HAMLET At supper. KING CLAUDIUS At supper! where? HAMLET Not where he eats, but where he is eaten: a certain convocation of politic worms are e'en at him. Your worm is your only emperor for diet: we fat all creatures else to fat us, and we fat ourselves for maggots: your fat king and your lean beggar is but variable service, two dishes, but to one table: that's the end. KING CLAUDIUS Alas, alas! HAMLET A man may fish with the worm that hath eat of a king, and cat of the fish that hath fed of that worm. KING CLAUDIUS What dost you mean by this? HAMLET Nothing but to show you how a king may go a progress through the guts of a beggar. KING CLAUDIUS Where is Polonius? HAMLET In heaven; send hither to see: if your messenger find him not there, seek him i' the other place yourself. But indeed, if you find him not within this month, you shall nose him as you go up the stairs into the lobby. KING CLAUDIUS Go seek him there. To some Attendants HAMLET He will stay till ye come. Exeunt Attendants KING CLAUDIUS Hamlet, this deed, for thine especial safety,-- Which we do tender, as we dearly grieve For that which thou hast done,--must send thee hence With fiery quickness: therefore prepare thyself; The bark is ready, and the wind at help, The associates tend, and every thing is bent For England. HAMLET For England! KING CLAUDIUS Ay, Hamlet. HAMLET Good. KING CLAUDIUS So is it, if thou knew'st our purposes. HAMLET I see a cherub that sees them. But, come; for England! Farewell, dear mother. KING CLAUDIUS Thy loving father, Hamlet. HAMLET My mother: father and mother is man and wife; man and wife is one flesh; and so, my mother. Come, for England! Exit KING CLAUDIUS Follow him at foot; tempt him with speed aboard; Delay it not; I'll have him hence to-night: Away! for every thing is seal'd and done That else leans on the affair: pray you, make haste. Exeunt ROSENCRANTZ and GUILDENSTERN And, England, if my love thou hold'st at aught-- As my great power thereof may give thee sense, Since yet thy cicatrice looks raw and red After the Danish sword, and thy free awe Pays homage to us--thou mayst not coldly set Our sovereign process; which imports at full, By letters congruing to that effect, The present death of Hamlet. Do it, England; For like the hectic in my blood he rages, And thou must cure me: till I know 'tis done, Howe'er my haps, my joys were ne'er begun. Exit SCENE IV. A plain in Denmark. Enter FORTINBRAS, a Captain, and Soldiers, marching PRINCE FORTINBRAS Go, captain, from me greet the Danish king; Tell him that, by his licence, Fortinbras Craves the conveyance of a promised march Over his kingdom. You know the rendezvous. If that his majesty would aught with us, We shall express our duty in his eye; And let him know so. Captain I will do't, my lord. PRINCE FORTINBRAS Go softly on. Exeunt FORTINBRAS and Soldiers Enter HAMLET, ROSENCRANTZ, GUILDENSTERN, and others HAMLET Good sir, whose powers are these? Captain They are of Norway, sir. HAMLET How purposed, sir, I pray you? Captain Against some part of Poland. HAMLET Who commands them, sir? Captain The nephews to old Norway, Fortinbras. HAMLET Goes it against the main of Poland, sir, Or for some frontier? Captain Truly to speak, and with no addition, We go to gain a little patch of ground That hath in it no profit but the name. To pay five ducats, five, I would not farm it; Nor will it yield to Norway or the Pole A ranker rate, should it be sold in fee. HAMLET Why, then the Polack never will defend it. Captain Yes, it is already garrison'd. HAMLET Two thousand souls and twenty thousand ducats Will not debate the question of this straw: This is the imposthume of much wealth and peace, That inward breaks, and shows no cause without Why the man dies. I humbly thank you, sir. Captain God be wi' you, sir. Exit ROSENCRANTZ Wilt please you go, my lord? HAMLET I'll be with you straight go a little before. Exeunt all except HAMLET How all occasions do inform against me, And spur my dull revenge! What is a man, If his chief good and market of his time Be but to sleep and feed? a beast, no more. Sure, he that made us with such large discourse, Looking before and after, gave us not That capability and god-like reason To fust in us unused. Now, whether it be Bestial oblivion, or some craven scruple Of thinking too precisely on the event, A thought which, quarter'd, hath but one part wisdom And ever three parts coward, I do not know Why yet I live to say 'This thing's to do;' Sith I have cause and will and strength and means To do't. Examples gross as earth exhort me: Witness this army of such mass and charge Led by a delicate and tender prince, Whose spirit with divine ambition puff'd Makes mouths at the invisible event, Exposing what is mortal and unsure To all that fortune, death and danger dare, Even for an egg-shell. Rightly to be great Is not to stir without great argument, But greatly to find quarrel in a straw When honour's at the stake. How stand I then, That have a father kill'd, a mother stain'd, Excitements of my reason and my blood, And let all sleep? while, to my shame, I see The imminent death of twenty thousand men, That, for a fantasy and trick of fame, Go to their graves like beds, fight for a plot Whereon the numbers cannot try the cause, Which is not tomb enough and continent To hide the slain? O, from this time forth, My thoughts be bloody, or be nothing worth! Exit SCENE V. Elsinore. A room in the castle. Enter QUEEN GERTRUDE, HORATIO, and a Gentleman QUEEN GERTRUDE I will not speak with her. Gentleman She is importunate, indeed distract: Her mood will needs be pitied. QUEEN GERTRUDE What would she have? Gentleman She speaks much of her father; says she hears There's tricks i' the world; and hems, and beats her heart; Spurns enviously at straws; speaks things in doubt, That carry but half sense: her speech is nothing, Yet the unshaped use of it doth move The hearers to collection; they aim at it, And botch the words up fit to their own thoughts; Which, as her winks, and nods, and gestures yield them, Indeed would make one think there might be thought, Though nothing sure, yet much unhappily. HORATIO 'Twere good she were spoken with; for she may strew Dangerous conjectures in ill-breeding minds. QUEEN GERTRUDE Let her come in. Exit HORATIO To my sick soul, as sin's true nature is, Each toy seems prologue to some great amiss: So full of artless jealousy is guilt, It spills itself in fearing to be spilt. Re-enter HORATIO, with OPHELIA OPHELIA Where is the beauteous majesty of Denmark? QUEEN GERTRUDE How now, Ophelia! OPHELIA Sings How should I your true love know From another one? By his cockle hat and staff, And his sandal shoon. QUEEN GERTRUDE Alas, sweet lady, what imports this song? OPHELIA Say you? nay, pray you, mark. Sings He is dead and gone, lady, He is dead and gone; At his head a grass-green turf, At his heels a stone. QUEEN GERTRUDE Nay, but, Ophelia,-- OPHELIA Pray you, mark. Sings White his shroud as the mountain snow,-- Enter KING CLAUDIUS QUEEN GERTRUDE Alas, look here, my lord. OPHELIA Sings Larded with sweet flowers Which bewept to the grave did go With true-love showers. KING CLAUDIUS How do you, pretty lady? OPHELIA Well, God 'ild you! They say the owl was a baker's daughter. Lord, we know what we are, but know not what we may be. God be at your table! KING CLAUDIUS Conceit upon her father. OPHELIA Pray you, let's have no words of this; but when they ask you what it means, say you this: Sings To-morrow is Saint Valentine's day, All in the morning betime, And I a maid at your window, To be your Valentine. Then up he rose, and donn'd his clothes, And dupp'd the chamber-door; Let in the maid, that out a maid Never departed more. KING CLAUDIUS Pretty Ophelia! OPHELIA Indeed, la, without an oath, I'll make an end on't: Sings By Gis and by Saint Charity, Alack, and fie for shame! Young men will do't, if they come to't; By cock, they are to blame. Quoth she, before you tumbled me, You promised me to wed. So would I ha' done, by yonder sun, An thou hadst not come to my bed. KING CLAUDIUS How long hath she been thus? OPHELIA I hope all will be well. We must be patient: but I cannot choose but weep, to think they should lay him i' the cold ground. My brother shall know of it: and so I thank you for your good counsel. Come, my coach! Good night, ladies; good night, sweet ladies; good night, good night. Exit KING CLAUDIUS Follow her close; give her good watch, I pray you. Exit HORATIO O, this is the poison of deep grief; it springs All from her father's death. O Gertrude, Gertrude, When sorrows come, they come not single spies But in battalions. First, her father slain: Next, your son gone; and he most violent author Of his own just remove: the people muddied, Thick and unwholesome in their thoughts and whispers, For good Polonius' death; and we have done but greenly, In hugger-mugger to inter him: poor Ophelia Divided from herself and her fair judgment, Without the which we are pictures, or mere beasts: Last, and as much containing as all these, Her brother is in secret come from France; Feeds on his wonder, keeps himself in clouds, And wants not buzzers to infect his ear With pestilent speeches of his father's death; Wherein necessity, of matter beggar'd, Will nothing stick our person to arraign In ear and ear. O my dear Gertrude, this, Like to a murdering-piece, in many places Gives me superfluous death. A noise within QUEEN GERTRUDE Alack, what noise is this? KING CLAUDIUS Where are my Switzers? Let them guard the door. Enter another Gentleman What is the matter? Gentleman Save yourself, my lord: The ocean, overpeering of his list, Eats not the flats with more impetuous haste Than young Laertes, in a riotous head, O'erbears your officers. The rabble call him lord; And, as the world were now but to begin, Antiquity forgot, custom not known, The ratifiers and props of every word, They cry 'Choose we: Laertes shall be king:' Caps, hands, and tongues, applaud it to the clouds: 'Laertes shall be king, Laertes king!' QUEEN GERTRUDE How cheerfully on the false trail they cry! O, this is counter, you false Danish dogs! KING CLAUDIUS The doors are broke. Noise within Enter LAERTES, armed; Danes following LAERTES Where is this king? Sirs, stand you all without. Danes No, let's come in. LAERTES I pray you, give me leave. Danes We will, we will. They retire without the door LAERTES I thank you: keep the door. O thou vile king, Give me my father! QUEEN GERTRUDE Calmly, good Laertes. LAERTES That drop of blood that's calm proclaims me bastard, Cries cuckold to my father, brands the harlot Even here, between the chaste unsmirched brow Of my true mother. KING CLAUDIUS What is the cause, Laertes, That thy rebellion looks so giant-like? Let him go, Gertrude; do not fear our person: There's such divinity doth hedge a king, That treason can but peep to what it would, Acts little of his will. Tell me, Laertes, Why thou art thus incensed. Let him go, Gertrude. Speak, man. LAERTES Where is my father? KING CLAUDIUS Dead. QUEEN GERTRUDE But not by him. KING CLAUDIUS Let him demand his fill. LAERTES How came he dead? I'll not be juggled with: To hell, allegiance! vows, to the blackest devil! Conscience and grace, to the profoundest pit! I dare damnation. To this point I stand, That both the worlds I give to negligence, Let come what comes; only I'll be revenged Most thoroughly for my father. KING CLAUDIUS Who shall stay you? LAERTES My will, not all the world: And for my means, I'll husband them so well, They shall go far with little. KING CLAUDIUS Good Laertes, If you desire to know the certainty Of your dear father's death, is't writ in your revenge, That, swoopstake, you will draw both friend and foe, Winner and loser? LAERTES None but his enemies. KING CLAUDIUS Will you know them then? LAERTES To his good friends thus wide I'll ope my arms; And like the kind life-rendering pelican, Repast them with my blood. KING CLAUDIUS Why, now you speak Like a good child and a true gentleman. That I am guiltless of your father's death, And am most sensible in grief for it, It shall as level to your judgment pierce As day does to your eye. Danes Within Let her come in. LAERTES How now! what noise is that? Re-enter OPHELIA O heat, dry up my brains! tears seven times salt, Burn out the sense and virtue of mine eye! By heaven, thy madness shall be paid by weight, Till our scale turn the beam. O rose of May! Dear maid, kind sister, sweet Ophelia! O heavens! is't possible, a young maid's wits Should be as moral as an old man's life? Nature is fine in love, and where 'tis fine, It sends some precious instance of itself After the thing it loves. OPHELIA Sings They bore him barefaced on the bier; Hey non nonny, nonny, hey nonny; And in his grave rain'd many a tear:-- Fare you well, my dove! LAERTES Hadst thou thy wits, and didst persuade revenge, It could not move thus. OPHELIA Sings You must sing a-down a-down, An you call him a-down-a. O, how the wheel becomes it! It is the false steward, that stole his master's daughter. LAERTES This nothing's more than matter. OPHELIA There's rosemary, that's for remembrance; pray, love, remember: and there is pansies. that's for thoughts. LAERTES A document in madness, thoughts and remembrance fitted. OPHELIA There's fennel for you, and columbines: there's rue for you; and here's some for me: we may call it herb-grace o' Sundays: O you must wear your rue with a difference. There's a daisy: I would give you some violets, but they withered all when my father died: they say he made a good end,-- Sings For bonny sweet Robin is all my joy. LAERTES Thought and affliction, passion, hell itself, She turns to favour and to prettiness. OPHELIA Sings And will he not come again? And will he not come again? No, no, he is dead: Go to thy death-bed: He never will come again. His beard was as white as snow, All flaxen was his poll: He is gone, he is gone, And we cast away moan: God ha' mercy on his soul! And of all Christian souls, I pray God. God be wi' ye. Exit LAERTES Do you see this, O God? KING CLAUDIUS Laertes, I must commune with your grief, Or you deny me right. Go but apart, Make choice of whom your wisest friends you will. And they shall hear and judge 'twixt you and me: If by direct or by collateral hand They find us touch'd, we will our kingdom give, Our crown, our life, and all that we can ours, To you in satisfaction; but if not, Be you content to lend your patience to us, And we shall jointly labour with your soul To give it due content. LAERTES Let this be so; His means of death, his obscure funeral-- No trophy, sword, nor hatchment o'er his bones, No noble rite nor formal ostentation-- Cry to be heard, as 'twere from heaven to earth, That I must call't in question. KING CLAUDIUS So you shall; And where the offence is let the great axe fall. I pray you, go with me. Exeunt SCENE VI. Another room in the castle. Enter HORATIO and a Servant HORATIO What are they that would speak with me? Servant Sailors, sir: they say they have letters for you. HORATIO Let them come in. Exit Servant I do not know from what part of the world I should be greeted, if not from Lord Hamlet. Enter Sailors First Sailor God bless you, sir. HORATIO Let him bless thee too. First Sailor He shall, sir, an't please him. There's a letter for you, sir; it comes from the ambassador that was bound for England; if your name be Horatio, as I am let to know it is. HORATIO Reads 'Horatio, when thou shalt have overlooked this, give these fellows some means to the king: they have letters for him. Ere we were two days old at sea, a pirate of very warlike appointment gave us chase. Finding ourselves too slow of sail, we put on a compelled valour, and in the grapple I boarded them: on the instant they got clear of our ship; so I alone became their prisoner. They have dealt with me like thieves of mercy: but they knew what they did; I am to do a good turn for them. Let the king have the letters I have sent; and repair thou to me with as much speed as thou wouldst fly death. I have words to speak in thine ear will make thee dumb; yet are they much too light for the bore of the matter. These good fellows will bring thee where I am. Rosencrantz and Guildenstern hold their course for England: of them I have much to tell thee. Farewell. 'He that thou knowest thine, HAMLET.' Come, I will make you way for these your letters; And do't the speedier, that you may direct me To him from whom you brought them. Exeunt SCENE VII. Another room in the castle. Enter KING CLAUDIUS and LAERTES KING CLAUDIUS Now must your conscience my acquaintance seal, And you must put me in your heart for friend, Sith you have heard, and with a knowing ear, That he which hath your noble father slain Pursued my life. LAERTES It well appears: but tell me Why you proceeded not against these feats, So crimeful and so capital in nature, As by your safety, wisdom, all things else, You mainly were stirr'd up. KING CLAUDIUS O, for two special reasons; Which may to you, perhaps, seem much unsinew'd, But yet to me they are strong. The queen his mother Lives almost by his looks; and for myself-- My virtue or my plague, be it either which-- She's so conjunctive to my life and soul, That, as the star moves not but in his sphere, I could not but by her. The other motive, Why to a public count I might not go, Is the great love the general gender bear him; Who, dipping all his faults in their affection, Would, like the spring that turneth wood to stone, Convert his gyves to graces; so that my arrows, Too slightly timber'd for so loud a wind, Would have reverted to my bow again, And not where I had aim'd them. LAERTES And so have I a noble father lost; A sister driven into desperate terms, Whose worth, if praises may go back again, Stood challenger on mount of all the age For her perfections: but my revenge will come. KING CLAUDIUS Break not your sleeps for that: you must not think That we are made of stuff so flat and dull That we can let our beard be shook with danger And think it pastime. You shortly shall hear more: I loved your father, and we love ourself; And that, I hope, will teach you to imagine-- Enter a Messenger How now! what news? Messenger Letters, my lord, from Hamlet: This to your majesty; this to the queen. KING CLAUDIUS From Hamlet! who brought them? Messenger Sailors, my lord, they say; I saw them not: They were given me by Claudio; he received them Of him that brought them. KING CLAUDIUS Laertes, you shall hear them. Leave us. Exit Messenger Reads 'High and mighty, You shall know I am set naked on your kingdom. To-morrow shall I beg leave to see your kingly eyes: when I shall, first asking your pardon thereunto, recount the occasion of my sudden and more strange return. 'HAMLET.' What should this mean? Are all the rest come back? Or is it some abuse, and no such thing? LAERTES Know you the hand? KING CLAUDIUS 'Tis Hamlets character. 'Naked! And in a postscript here, he says 'alone.' Can you advise me? LAERTES I'm lost in it, my lord. But let him come; It warms the very sickness in my heart, That I shall live and tell him to his teeth, 'Thus didest thou.' KING CLAUDIUS If it be so, Laertes-- As how should it be so? how otherwise?-- Will you be ruled by me? LAERTES Ay, my lord; So you will not o'errule me to a peace. KING CLAUDIUS To thine own peace. If he be now return'd, As checking at his voyage, and that he means No more to undertake it, I will work him To an exploit, now ripe in my device, Under the which he shall not choose but fall: And for his death no wind of blame shall breathe, But even his mother shall uncharge the practise And call it accident. LAERTES My lord, I will be ruled; The rather, if you could devise it so That I might be the organ. KING CLAUDIUS It falls right. You have been talk'd of since your travel much, And that in Hamlet's hearing, for a quality Wherein, they say, you shine: your sum of parts Did not together pluck such envy from him As did that one, and that, in my regard, Of the unworthiest siege. LAERTES What part is that, my lord? KING CLAUDIUS A very riband in the cap of youth, Yet needful too; for youth no less becomes The light and careless livery that it wears Than settled age his sables and his weeds, Importing health and graveness. Two months since, Here was a gentleman of Normandy:-- I've seen myself, and served against, the French, And they can well on horseback: but this gallant Had witchcraft in't; he grew unto his seat; And to such wondrous doing brought his horse, As he had been incorpsed and demi-natured With the brave beast: so far he topp'd my thought, That I, in forgery of shapes and tricks, Come short of what he did. LAERTES A Norman was't? KING CLAUDIUS A Norman. LAERTES Upon my life, Lamond. KING CLAUDIUS The very same. LAERTES I know him well: he is the brooch indeed And gem of all the nation. KING CLAUDIUS He made confession of you, And gave you such a masterly report For art and exercise in your defence And for your rapier most especially, That he cried out, 'twould be a sight indeed, If one could match you: the scrimers of their nation, He swore, had had neither motion, guard, nor eye, If you opposed them. Sir, this report of his Did Hamlet so envenom with his envy That he could nothing do but wish and beg Your sudden coming o'er, to play with him. Now, out of this,-- LAERTES What out of this, my lord? KING CLAUDIUS Laertes, was your father dear to you? Or are you like the painting of a sorrow, A face without a heart? LAERTES Why ask you this? KING CLAUDIUS Not that I think you did not love your father; But that I know love is begun by time; And that I see, in passages of proof, Time qualifies the spark and fire of it. There lives within the very flame of love A kind of wick or snuff that will abate it; And nothing is at a like goodness still; For goodness, growing to a plurisy, Dies in his own too much: that we would do We should do when we would; for this 'would' changes And hath abatements and delays as many As there are tongues, are hands, are accidents; And then this 'should' is like a spendthrift sigh, That hurts by easing. But, to the quick o' the ulcer:-- Hamlet comes back: what would you undertake, To show yourself your father's son in deed More than in words? LAERTES To cut his throat i' the church. KING CLAUDIUS No place, indeed, should murder sanctuarize; Revenge should have no bounds. But, good Laertes, Will you do this, keep close within your chamber. Hamlet return'd shall know you are come home: We'll put on those shall praise your excellence And set a double varnish on the fame The Frenchman gave you, bring you in fine together And wager on your heads: he, being remiss, Most generous and free from all contriving, Will not peruse the foils; so that, with ease, Or with a little shuffling, you may choose A sword unbated, and in a pass of practise Requite him for your father. LAERTES I will do't: And, for that purpose, I'll anoint my sword. I bought an unction of a mountebank, So mortal that, but dip a knife in it, Where it draws blood no cataplasm so rare, Collected from all simples that have virtue Under the moon, can save the thing from death That is but scratch'd withal: I'll touch my point With this contagion, that, if I gall him slightly, It may be death. KING CLAUDIUS Let's further think of this; Weigh what convenience both of time and means May fit us to our shape: if this should fail, And that our drift look through our bad performance, 'Twere better not assay'd: therefore this project Should have a back or second, that might hold, If this should blast in proof. Soft! let me see: We'll make a solemn wager on your cunnings: I ha't. When in your motion you are hot and dry-- As make your bouts more violent to that end-- And that he calls for drink, I'll have prepared him A chalice for the nonce, whereon but sipping, If he by chance escape your venom'd stuck, Our purpose may hold there. Enter QUEEN GERTRUDE How now, sweet queen! QUEEN GERTRUDE One woe doth tread upon another's heel, So fast they follow; your sister's drown'd, Laertes. LAERTES Drown'd! O, where? QUEEN GERTRUDE There is a willow grows aslant a brook, That shows his hoar leaves in the glassy stream; There with fantastic garlands did she come Of crow-flowers, nettles, daisies, and long purples That liberal shepherds give a grosser name, But our cold maids do dead men's fingers call them: There, on the pendent boughs her coronet weeds Clambering to hang, an envious sliver broke; When down her weedy trophies and herself Fell in the weeping brook. Her clothes spread wide; And, mermaid-like, awhile they bore her up: Which time she chanted snatches of old tunes; As one incapable of her own distress, Or like a creature native and indued Unto that element: but long it could not be Till that her garments, heavy with their drink, Pull'd the poor wretch from her melodious lay To muddy death. LAERTES Alas, then, she is drown'd? QUEEN GERTRUDE Drown'd, drown'd. LAERTES Too much of water hast thou, poor Ophelia, And therefore I forbid my tears: but yet It is our trick; nature her custom holds, Let shame say what it will: when these are gone, The woman will be out. Adieu, my lord: I have a speech of fire, that fain would blaze, But that this folly douts it. Exit KING CLAUDIUS Let's follow, Gertrude: How much I had to do to calm his rage! Now fear I this will give it start again; Therefore let's follow. Exeunt ACT V SCENE I. A churchyard. Enter two Clowns, with spades, &c First Clown Is she to be buried in Christian burial that wilfully seeks her own salvation? Second Clown I tell thee she is: and therefore make her grave straight: the crowner hath sat on her, and finds it Christian burial. First Clown How can that be, unless she drowned herself in her own defence? Second Clown Why, 'tis found so. First Clown It must be 'se offendendo;' it cannot be else. For here lies the point: if I drown myself wittingly, it argues an act: and an act hath three branches: it is, to act, to do, to perform: argal, she drowned herself wittingly. Second Clown Nay, but hear you, goodman delver,-- First Clown Give me leave. Here lies the water; good: here stands the man; good; if the man go to this water, and drown himself, it is, will he, nill he, he goes,--mark you that; but if the water come to him and drown him, he drowns not himself: argal, he that is not guilty of his own death shortens not his own life. Second Clown But is this law? First Clown Ay, marry, is't; crowner's quest law. Second Clown Will you ha' the truth on't? If this had not been a gentlewoman, she should have been buried out o' Christian burial. First Clown Why, there thou say'st: and the more pity that great folk should have countenance in this world to drown or hang themselves, more than their even Christian. Come, my spade. There is no ancient gentleman but gardeners, ditchers, and grave-makers: they hold up Adam's profession. Second Clown Was he a gentleman? First Clown He was the first that ever bore arms. Second Clown Why, he had none. First Clown What, art a heathen? How dost thou understand the Scripture? The Scripture says 'Adam digged:' could he dig without arms? I'll put another question to thee: if thou answerest me not to the purpose, confess thyself-- Second Clown Go to. First Clown What is he that builds stronger than either the mason, the shipwright, or the carpenter? Second Clown The gallows-maker; for that frame outlives a thousand tenants. First Clown I like thy wit well, in good faith: the gallows does well; but how does it well? it does well to those that do in: now thou dost ill to say the gallows is built stronger than the church: argal, the gallows may do well to thee. To't again, come. Second Clown 'Who builds stronger than a mason, a shipwright, or a carpenter?' First Clown Ay, tell me that, and unyoke. Second Clown Marry, now I can tell. First Clown To't. Second Clown Mass, I cannot tell. Enter HAMLET and HORATIO, at a distance First Clown Cudgel thy brains no more about it, for your dull ass will not mend his pace with beating; and, when you are asked this question next, say 'a grave-maker: 'the houses that he makes last till doomsday. Go, get thee to Yaughan: fetch me a stoup of liquor. Exit Second Clown He digs and sings In youth, when I did love, did love, Methought it was very sweet, To contract, O, the time, for, ah, my behove, O, methought, there was nothing meet. HAMLET Has this fellow no feeling of his business, that he sings at grave-making? HORATIO Custom hath made it in him a property of easiness. HAMLET 'Tis e'en so: the hand of little employment hath the daintier sense. First Clown Sings But age, with his stealing steps, Hath claw'd me in his clutch, And hath shipped me intil the land, As if I had never been such. Throws up a skull HAMLET That skull had a tongue in it, and could sing once: how the knave jowls it to the ground, as if it were Cain's jaw-bone, that did the first murder! It might be the pate of a politician, which this ass now o'er-reaches; one that would circumvent God, might it not? HORATIO It might, my lord. HAMLET Or of a courtier; which could say 'Good morrow, sweet lord! How dost thou, good lord?' This might be my lord such-a-one, that praised my lord such-a-one's horse, when he meant to beg it; might it not? HORATIO Ay, my lord. HAMLET Why, e'en so: and now my Lady Worm's; chapless, and knocked about the mazzard with a sexton's spade: here's fine revolution, an we had the trick to see't. Did these bones cost no more the breeding, but to play at loggats with 'em? mine ache to think on't. First Clown Sings A pick-axe, and a spade, a spade, For and a shrouding sheet: O, a pit of clay for to be made For such a guest is meet. Throws up another skull HAMLET There's another: why may not that be the skull of a lawyer? Where be his quiddities now, his quillets, his cases, his tenures, and his tricks? why does he suffer this rude knave now to knock him about the sconce with a dirty shovel, and will not tell him of his action of battery? Hum! This fellow might be in's time a great buyer of land, with his statutes, his recognizances, his fines, his double vouchers, his recoveries: is this the fine of his fines, and the recovery of his recoveries, to have his fine pate full of fine dirt? will his vouchers vouch him no more of his purchases, and double ones too, than the length and breadth of a pair of indentures? The very conveyances of his lands will hardly lie in this box; and must the inheritor himself have no more, ha? HORATIO Not a jot more, my lord. HAMLET Is not parchment made of sheepskins? HORATIO Ay, my lord, and of calf-skins too. HAMLET They are sheep and calves which seek out assurance in that. I will speak to this fellow. Whose grave's this, sirrah? First Clown Mine, sir. Sings O, a pit of clay for to be made For such a guest is meet. HAMLET I think it be thine, indeed; for thou liest in't. First Clown You lie out on't, sir, and therefore it is not yours: for my part, I do not lie in't, and yet it is mine. HAMLET 'Thou dost lie in't, to be in't and say it is thine: 'tis for the dead, not for the quick; therefore thou liest. First Clown 'Tis a quick lie, sir; 'twill away gain, from me to you. HAMLET What man dost thou dig it for? First Clown For no man, sir. HAMLET What woman, then? First Clown For none, neither. HAMLET Who is to be buried in't? First Clown One that was a woman, sir; but, rest her soul, she's dead. HAMLET How absolute the knave is! we must speak by the card, or equivocation will undo us. By the Lord, Horatio, these three years I have taken a note of it; the age is grown so picked that the toe of the peasant comes so near the heel of the courtier, he gaffs his kibe. How long hast thou been a grave-maker? First Clown Of all the days i' the year, I came to't that day that our last king Hamlet overcame Fortinbras. HAMLET How long is that since? First Clown Cannot you tell that? every fool can tell that: it was the very day that young Hamlet was born; he that is mad, and sent into England. HAMLET Ay, marry, why was he sent into England? First Clown Why, because he was mad: he shall recover his wits there; or, if he do not, it's no great matter there. HAMLET Why? First Clown 'Twill, a not be seen in him there; there the men are as mad as he. HAMLET How came he mad? First Clown Very strangely, they say. HAMLET How strangely? First Clown Faith, e'en with losing his wits. HAMLET Upon what ground? First Clown Why, here in Denmark: I have been sexton here, man and boy, thirty years. HAMLET How long will a man lie i' the earth ere he rot? First Clown I' faith, if he be not rotten before he die--as we have many pocky corses now-a-days, that will scarce hold the laying in--he will last you some eight year or nine year: a tanner will last you nine year. HAMLET Why he more than another? First Clown Why, sir, his hide is so tanned with his trade, that he will keep out water a great while; and your water is a sore decayer of your whoreson dead body. Here's a skull now; this skull has lain in the earth three and twenty years. HAMLET Whose was it? First Clown A whoreson mad fellow's it was: whose do you think it was? HAMLET Nay, I know not. First Clown A pestilence on him for a mad rogue! a' poured a flagon of Rhenish on my head once. This same skull, sir, was Yorick's skull, the king's jester. HAMLET This? First Clown E'en that. HAMLET Let me see. Takes the skull Alas, poor Yorick! I knew him, Horatio: a fellow of infinite jest, of most excellent fancy: he hath borne me on his back a thousand times; and now, how abhorred in my imagination it is! my gorge rims at it. Here hung those lips that I have kissed I know not how oft. Where be your gibes now? your gambols? your songs? your flashes of merriment, that were wont to set the table on a roar? Not one now, to mock your own grinning? quite chap-fallen? Now get you to my lady's chamber, and tell her, let her paint an inch thick, to this favour she must come; make her laugh at that. Prithee, Horatio, tell me one thing. HORATIO What's that, my lord? HAMLET Dost thou think Alexander looked o' this fashion i' the earth? HORATIO E'en so. HAMLET And smelt so? pah! Puts down the skull HORATIO E'en so, my lord. HAMLET To what base uses we may return, Horatio! Why may not imagination trace the noble dust of Alexander, till he find it stopping a bung-hole? HORATIO 'Twere to consider too curiously, to consider so. HAMLET No, faith, not a jot; but to follow him thither with modesty enough, and likelihood to lead it: as thus: Alexander died, Alexander was buried, Alexander returneth into dust; the dust is earth; of earth we make loam; and why of that loam, whereto he was converted, might they not stop a beer-barrel? Imperious Caesar, dead and turn'd to clay, Might stop a hole to keep the wind away: O, that that earth, which kept the world in awe, Should patch a wall to expel the winter flaw! But soft! but soft! aside: here comes the king. Enter Priest, &c. in procession; the Corpse of OPHELIA, LAERTES and Mourners following; KING CLAUDIUS, QUEEN GERTRUDE, their trains, &c The queen, the courtiers: who is this they follow? And with such maimed rites? This doth betoken The corse they follow did with desperate hand Fordo its own life: 'twas of some estate. Couch we awhile, and mark. Retiring with HORATIO LAERTES What ceremony else? HAMLET That is Laertes, A very noble youth: mark. LAERTES What ceremony else? First Priest Her obsequies have been as far enlarged As we have warrantise: her death was doubtful; And, but that great command o'ersways the order, She should in ground unsanctified have lodged Till the last trumpet: for charitable prayers, Shards, flints and pebbles should be thrown on her; Yet here she is allow'd her virgin crants, Her maiden strewments and the bringing home Of bell and burial. LAERTES Must there no more be done? First Priest No more be done: We should profane the service of the dead To sing a requiem and such rest to her As to peace-parted souls. LAERTES Lay her i' the earth: And from her fair and unpolluted flesh May violets spring! I tell thee, churlish priest, A ministering angel shall my sister be, When thou liest howling. HAMLET What, the fair Ophelia! QUEEN GERTRUDE Sweets to the sweet: farewell! Scattering flowers I hoped thou shouldst have been my Hamlet's wife; I thought thy bride-bed to have deck'd, sweet maid, And not have strew'd thy grave. LAERTES O, treble woe Fall ten times treble on that cursed head, Whose wicked deed thy most ingenious sense Deprived thee of! Hold off the earth awhile, Till I have caught her once more in mine arms: Leaps into the grave Now pile your dust upon the quick and dead, Till of this flat a mountain you have made, To o'ertop old Pelion, or the skyish head Of blue Olympus. HAMLET Advancing What is he whose grief Bears such an emphasis? whose phrase of sorrow Conjures the wandering stars, and makes them stand Like wonder-wounded hearers? This is I, Hamlet the Dane. Leaps into the grave LAERTES The devil take thy soul! Grappling with him HAMLET Thou pray'st not well. I prithee, take thy fingers from my throat; For, though I am not splenitive and rash, Yet have I something in me dangerous, Which let thy wiseness fear: hold off thy hand. KING CLAUDIUS Pluck them asunder. QUEEN GERTRUDE Hamlet, Hamlet! All Gentlemen,-- HORATIO Good my lord, be quiet. The Attendants part them, and they come out of the grave HAMLET Why I will fight with him upon this theme Until my eyelids will no longer wag. QUEEN GERTRUDE O my son, what theme? HAMLET I loved Ophelia: forty thousand brothers Could not, with all their quantity of love, Make up my sum. What wilt thou do for her? KING CLAUDIUS O, he is mad, Laertes. QUEEN GERTRUDE For love of God, forbear him. HAMLET 'Swounds, show me what thou'lt do: Woo't weep? woo't fight? woo't fast? woo't tear thyself? Woo't drink up eisel? eat a crocodile? I'll do't. Dost thou come here to whine? To outface me with leaping in her grave? Be buried quick with her, and so will I: And, if thou prate of mountains, let them throw Millions of acres on us, till our ground, Singeing his pate against the burning zone, Make Ossa like a wart! Nay, an thou'lt mouth, I'll rant as well as thou. QUEEN GERTRUDE This is mere madness: And thus awhile the fit will work on him; Anon, as patient as the female dove, When that her golden couplets are disclosed, His silence will sit drooping. HAMLET Hear you, sir; What is the reason that you use me thus? I loved you ever: but it is no matter; Let Hercules himself do what he may, The cat will mew and dog will have his day. Exit KING CLAUDIUS I pray you, good Horatio, wait upon him. Exit HORATIO To LAERTES Strengthen your patience in our last night's speech; We'll put the matter to the present push. Good Gertrude, set some watch over your son. This grave shall have a living monument: An hour of quiet shortly shall we see; Till then, in patience our proceeding be. Exeunt SCENE II. A hall in the castle. Enter HAMLET and HORATIO HAMLET So much for this, sir: now shall you see the other; You do remember all the circumstance? HORATIO Remember it, my lord? HAMLET Sir, in my heart there was a kind of fighting, That would not let me sleep: methought I lay Worse than the mutines in the bilboes. Rashly, And praised be rashness for it, let us know, Our indiscretion sometimes serves us well, When our deep plots do pall: and that should teach us There's a divinity that shapes our ends, Rough-hew them how we will,-- HORATIO That is most certain. HAMLET Up from my cabin, My sea-gown scarf'd about me, in the dark Groped I to find out them; had my desire. Finger'd their packet, and in fine withdrew To mine own room again; making so bold, My fears forgetting manners, to unseal Their grand commission; where I found, Horatio,-- O royal knavery!--an exact command, Larded with many several sorts of reasons Importing Denmark's health and England's too, With, ho! such bugs and goblins in my life, That, on the supervise, no leisure bated, No, not to stay the grinding of the axe, My head should be struck off. HORATIO Is't possible? HAMLET Here's the commission: read it at more leisure. But wilt thou hear me how I did proceed? HORATIO I beseech you. HAMLET Being thus be-netted round with villanies,-- Ere I could make a prologue to my brains, They had begun the play--I sat me down, Devised a new commission, wrote it fair: I once did hold it, as our statists do, A baseness to write fair and labour'd much How to forget that learning, but, sir, now It did me yeoman's service: wilt thou know The effect of what I wrote? HORATIO Ay, good my lord. HAMLET An earnest conjuration from the king, As England was his faithful tributary, As love between them like the palm might flourish, As peace should stiff her wheaten garland wear And stand a comma 'tween their amities, And many such-like 'As'es of great charge, That, on the view and knowing of these contents, Without debatement further, more or less, He should the bearers put to sudden death, Not shriving-time allow'd. HORATIO How was this seal'd? HAMLET Why, even in that was heaven ordinant. I had my father's signet in my purse, Which was the model of that Danish seal; Folded the writ up in form of the other, Subscribed it, gave't the impression, placed it safely, The changeling never known. Now, the next day Was our sea-fight; and what to this was sequent Thou know'st already. HORATIO So Guildenstern and Rosencrantz go to't. HAMLET Why, man, they did make love to this employment; They are not near my conscience; their defeat Does by their own insinuation grow: 'Tis dangerous when the baser nature comes Between the pass and fell incensed points Of mighty opposites. HORATIO Why, what a king is this! HAMLET Does it not, think'st thee, stand me now upon-- He that hath kill'd my king and whored my mother, Popp'd in between the election and my hopes, Thrown out his angle for my proper life, And with such cozenage--is't not perfect conscience, To quit him with this arm? and is't not to be damn'd, To let this canker of our nature come In further evil? HORATIO It must be shortly known to him from England What is the issue of the business there. HAMLET It will be short: the interim is mine; And a man's life's no more than to say 'One.' But I am very sorry, good Horatio, That to Laertes I forgot myself; For, by the image of my cause, I see The portraiture of his: I'll court his favours. But, sure, the bravery of his grief did put me Into a towering passion. HORATIO Peace! who comes here? Enter OSRIC OSRIC Your lordship is right welcome back to Denmark. HAMLET I humbly thank you, sir. Dost know this water-fly? HORATIO No, my good lord. HAMLET Thy state is the more gracious; for 'tis a vice to know him. He hath much land, and fertile: let a beast be lord of beasts, and his crib shall stand at the king's mess: 'tis a chough; but, as I say, spacious in the possession of dirt. OSRIC Sweet lord, if your lordship were at leisure, I should impart a thing to you from his majesty. HAMLET I will receive it, sir, with all diligence of spirit. Put your bonnet to his right use; 'tis for the head. OSRIC I thank your lordship, it is very hot. HAMLET No, believe me, 'tis very cold; the wind is northerly. OSRIC It is indifferent cold, my lord, indeed. HAMLET But yet methinks it is very sultry and hot for my complexion. OSRIC Exceedingly, my lord; it is very sultry,--as 'twere,--I cannot tell how. But, my lord, his majesty bade me signify to you that he has laid a great wager on your head: sir, this is the matter,-- HAMLET I beseech you, remember-- HAMLET moves him to put on his hat OSRIC Nay, good my lord; for mine ease, in good faith. Sir, here is newly come to court Laertes; believe me, an absolute gentleman, full of most excellent differences, of very soft society and great showing: indeed, to speak feelingly of him, he is the card or calendar of gentry, for you shall find in him the continent of what part a gentleman would see. HAMLET Sir, his definement suffers no perdition in you; though, I know, to divide him inventorially would dizzy the arithmetic of memory, and yet but yaw neither, in respect of his quick sail. But, in the verity of extolment, I take him to be a soul of great article; and his infusion of such dearth and rareness, as, to make true diction of him, his semblable is his mirror; and who else would trace him, his umbrage, nothing more. OSRIC Your lordship speaks most infallibly of him. HAMLET The concernancy, sir? why do we wrap the gentleman in our more rawer breath? OSRIC Sir? HORATIO Is't not possible to understand in another tongue? You will do't, sir, really. HAMLET What imports the nomination of this gentleman? OSRIC Of Laertes? HORATIO His purse is empty already; all's golden words are spent. HAMLET Of him, sir. OSRIC I know you are not ignorant-- HAMLET I would you did, sir; yet, in faith, if you did, it would not much approve me. Well, sir? OSRIC You are not ignorant of what excellence Laertes is-- HAMLET I dare not confess that, lest I should compare with him in excellence; but, to know a man well, were to know himself. OSRIC I mean, sir, for his weapon; but in the imputation laid on him by them, in his meed he's unfellowed. HAMLET What's his weapon? OSRIC Rapier and dagger. HAMLET That's two of his weapons: but, well. OSRIC The king, sir, hath wagered with him six Barbary horses: against the which he has imponed, as I take it, six French rapiers and poniards, with their assigns, as girdle, hangers, and so: three of the carriages, in faith, are very dear to fancy, very responsive to the hilts, most delicate carriages, and of very liberal conceit. HAMLET What call you the carriages? HORATIO I knew you must be edified by the margent ere you had done. OSRIC The carriages, sir, are the hangers. HAMLET The phrase would be more german to the matter, if we could carry cannon by our sides: I would it might be hangers till then. But, on: six Barbary horses against six French swords, their assigns, and three liberal-conceited carriages; that's the French bet against the Danish. Why is this 'imponed,' as you call it? OSRIC The king, sir, hath laid, that in a dozen passes between yourself and him, he shall not exceed you three hits: he hath laid on twelve for nine; and it would come to immediate trial, if your lordship would vouchsafe the answer. HAMLET How if I answer 'no'? OSRIC I mean, my lord, the opposition of your person in trial. HAMLET Sir, I will walk here in the hall: if it please his majesty, 'tis the breathing time of day with me; let the foils be brought, the gentleman willing, and the king hold his purpose, I will win for him an I can; if not, I will gain nothing but my shame and the odd hits. OSRIC Shall I re-deliver you e'en so? HAMLET To this effect, sir; after what flourish your nature will. OSRIC I commend my duty to your lordship. HAMLET Yours, yours. Exit OSRIC He does well to commend it himself; there are no tongues else for's turn. HORATIO This lapwing runs away with the shell on his head. HAMLET He did comply with his dug, before he sucked it. Thus has he--and many more of the same bevy that I know the dressy age dotes on--only got the tune of the time and outward habit of encounter; a kind of yesty collection, which carries them through and through the most fond and winnowed opinions; and do but blow them to their trial, the bubbles are out. Enter a Lord Lord My lord, his majesty commended him to you by young Osric, who brings back to him that you attend him in the hall: he sends to know if your pleasure hold to play with Laertes, or that you will take longer time. HAMLET I am constant to my purpose; they follow the king's pleasure: if his fitness speaks, mine is ready; now or whensoever, provided I be so able as now. Lord The king and queen and all are coming down. HAMLET In happy time. Lord The queen desires you to use some gentle entertainment to Laertes before you fall to play. HAMLET She well instructs me. Exit Lord HORATIO You will lose this wager, my lord. HAMLET I do not think so: since he went into France, I have been in continual practise: I shall win at the odds. But thou wouldst not think how ill all's here about my heart: but it is no matter. HORATIO Nay, good my lord,-- HAMLET It is but foolery; but it is such a kind of gain-giving, as would perhaps trouble a woman. HORATIO If your mind dislike any thing, obey it: I will forestall their repair hither, and say you are not fit. HAMLET Not a whit, we defy augury: there's a special providence in the fall of a sparrow. If it be now, 'tis not to come; if it be not to come, it will be now; if it be not now, yet it will come: the readiness is all: since no man has aught of what he leaves, what is't to leave betimes? Enter KING CLAUDIUS, QUEEN GERTRUDE, LAERTES, Lords, OSRIC, and Attendants with foils, &c KING CLAUDIUS Come, Hamlet, come, and take this hand from me. KING CLAUDIUS puts LAERTES' hand into HAMLET's HAMLET Give me your pardon, sir: I've done you wrong; But pardon't, as you are a gentleman. This presence knows, And you must needs have heard, how I am punish'd With sore distraction. What I have done, That might your nature, honour and exception Roughly awake, I here proclaim was madness. Was't Hamlet wrong'd Laertes? Never Hamlet: If Hamlet from himself be ta'en away, And when he's not himself does wrong Laertes, Then Hamlet does it not, Hamlet denies it. Who does it, then? His madness: if't be so, Hamlet is of the faction that is wrong'd; His madness is poor Hamlet's enemy. Sir, in this audience, Let my disclaiming from a purposed evil Free me so far in your most generous thoughts, That I have shot mine arrow o'er the house, And hurt my brother. LAERTES I am satisfied in nature, Whose motive, in this case, should stir me most To my revenge: but in my terms of honour I stand aloof; and will no reconcilement, Till by some elder masters, of known honour, I have a voice and precedent of peace, To keep my name ungored. But till that time, I do receive your offer'd love like love, And will not wrong it. HAMLET I embrace it freely; And will this brother's wager frankly play. Give us the foils. Come on. LAERTES Come, one for me. HAMLET I'll be your foil, Laertes: in mine ignorance Your skill shall, like a star i' the darkest night, Stick fiery off indeed. LAERTES You mock me, sir. HAMLET No, by this hand. KING CLAUDIUS Give them the foils, young Osric. Cousin Hamlet, You know the wager? HAMLET Very well, my lord Your grace hath laid the odds o' the weaker side. KING CLAUDIUS I do not fear it; I have seen you both: But since he is better'd, we have therefore odds. LAERTES This is too heavy, let me see another. HAMLET This likes me well. These foils have all a length? They prepare to play OSRIC Ay, my good lord. KING CLAUDIUS Set me the stoops of wine upon that table. If Hamlet give the first or second hit, Or quit in answer of the third exchange, Let all the battlements their ordnance fire: The king shall drink to Hamlet's better breath; And in the cup an union shall he throw, Richer than that which four successive kings In Denmark's crown have worn. Give me the cups; And let the kettle to the trumpet speak, The trumpet to the cannoneer without, The cannons to the heavens, the heavens to earth, 'Now the king dunks to Hamlet.' Come, begin: And you, the judges, bear a wary eye. HAMLET Come on, sir. LAERTES Come, my lord. They play HAMLET One. LAERTES No. HAMLET Judgment. OSRIC A hit, a very palpable hit. LAERTES Well; again. KING CLAUDIUS Stay; give me drink. Hamlet, this pearl is thine; Here's to thy health. Trumpets sound, and cannon shot off within Give him the cup. HAMLET I'll play this bout first; set it by awhile. Come. They play Another hit; what say you? LAERTES A touch, a touch, I do confess. KING CLAUDIUS Our son shall win. QUEEN GERTRUDE He's fat, and scant of breath. Here, Hamlet, take my napkin, rub thy brows; The queen carouses to thy fortune, Hamlet. HAMLET Good madam! KING CLAUDIUS Gertrude, do not drink. QUEEN GERTRUDE I will, my lord; I pray you, pardon me. KING CLAUDIUS Aside It is the poison'd cup: it is too late. HAMLET I dare not drink yet, madam; by and by. QUEEN GERTRUDE Come, let me wipe thy face. LAERTES My lord, I'll hit him now. KING CLAUDIUS I do not think't. LAERTES Aside And yet 'tis almost 'gainst my conscience. HAMLET Come, for the third, Laertes: you but dally; I pray you, pass with your best violence; I am afeard you make a wanton of me. LAERTES Say you so? come on. They play OSRIC Nothing, neither way. LAERTES Have at you now! LAERTES wounds HAMLET; then in scuffling, they change rapiers, and HAMLET wounds LAERTES KING CLAUDIUS Part them; they are incensed. HAMLET Nay, come, again. QUEEN GERTRUDE falls OSRIC Look to the queen there, ho! HORATIO They bleed on both sides. How is it, my lord? OSRIC How is't, Laertes? LAERTES Why, as a woodcock to mine own springe, Osric; I am justly kill'd with mine own treachery. HAMLET How does the queen? KING CLAUDIUS She swounds to see them bleed. QUEEN GERTRUDE No, no, the drink, the drink,--O my dear Hamlet,-- The drink, the drink! I am poison'd. Dies HAMLET O villany! Ho! let the door be lock'd: Treachery! Seek it out. LAERTES It is here, Hamlet: Hamlet, thou art slain; No medicine in the world can do thee good; In thee there is not half an hour of life; The treacherous instrument is in thy hand, Unbated and envenom'd: the foul practise Hath turn'd itself on me lo, here I lie, Never to rise again: thy mother's poison'd: I can no more: the king, the king's to blame. HAMLET The point!--envenom'd too! Then, venom, to thy work. Stabs KING CLAUDIUS All Treason! treason! KING CLAUDIUS O, yet defend me, friends; I am but hurt. HAMLET Here, thou incestuous, murderous, damned Dane, Drink off this potion. Is thy union here? Follow my mother. KING CLAUDIUS dies LAERTES He is justly served; It is a poison temper'd by himself. Exchange forgiveness with me, noble Hamlet: Mine and my father's death come not upon thee, Nor thine on me. Dies HAMLET Heaven make thee free of it! I follow thee. I am dead, Horatio. Wretched queen, adieu! You that look pale and tremble at this chance, That are but mutes or audience to this act, Had I but time--as this fell sergeant, death, Is strict in his arrest--O, I could tell you-- But let it be. Horatio, I am dead; Thou livest; report me and my cause aright To the unsatisfied. HORATIO Never believe it: I am more an antique Roman than a Dane: Here's yet some liquor left. HAMLET As thou'rt a man, Give me the cup: let go; by heaven, I'll have't. O good Horatio, what a wounded name, Things standing thus unknown, shall live behind me! If thou didst ever hold me in thy heart Absent thee from felicity awhile, And in this harsh world draw thy breath in pain, To tell my story. March afar off, and shot within What warlike noise is this? OSRIC Young Fortinbras, with conquest come from Poland, To the ambassadors of England gives This warlike volley. HAMLET O, I die, Horatio; The potent poison quite o'er-crows my spirit: I cannot live to hear the news from England; But I do prophesy the election lights On Fortinbras: he has my dying voice; So tell him, with the occurrents, more and less, Which have solicited. The rest is silence. Dies HORATIO Now cracks a noble heart. Good night sweet prince: And flights of angels sing thee to thy rest! Why does the drum come hither? March within Enter FORTINBRAS, the English Ambassadors, and others PRINCE FORTINBRAS Where is this sight? HORATIO What is it ye would see? If aught of woe or wonder, cease your search. PRINCE FORTINBRAS This quarry cries on havoc. O proud death, What feast is toward in thine eternal cell, That thou so many princes at a shot So bloodily hast struck? First Ambassador The sight is dismal; And our affairs from England come too late: The ears are senseless that should give us hearing, To tell him his commandment is fulfill'd, That Rosencrantz and Guildenstern are dead: Where should we have our thanks? HORATIO Not from his mouth, Had it the ability of life to thank you: He never gave commandment for their death. But since, so jump upon this bloody question, You from the Polack wars, and you from England, Are here arrived give order that these bodies High on a stage be placed to the view; And let me speak to the yet unknowing world How these things came about: so shall you hear Of carnal, bloody, and unnatural acts, Of accidental judgments, casual slaughters, Of deaths put on by cunning and forced cause, And, in this upshot, purposes mistook Fall'n on the inventors' reads: all this can I Truly deliver. PRINCE FORTINBRAS Let us haste to hear it, And call the noblest to the audience. For me, with sorrow I embrace my fortune: I have some rights of memory in this kingdom, Which now to claim my vantage doth invite me. HORATIO Of that I shall have also cause to speak, And from his mouth whose voice will draw on more; But let this same be presently perform'd, Even while men's minds are wild; lest more mischance On plots and errors, happen. PRINCE FORTINBRAS Let four captains Bear Hamlet, like a soldier, to the stage; For he was likely, had he been put on, To have proved most royally: and, for his passage, The soldiers' music and the rites of war Speak loudly for him. Take up the bodies: such a sight as this Becomes the field, but here shows much amiss. Go, bid the soldiers shoot. A dead march. Exeunt, bearing off the dead bodies; after which a peal of ordnance is shot off
libxml-ruby-3.2.1/script/benchmark/throughput0000644000004100000410000000162213760147770021422 0ustar www-datawww-data#!/usr/bin/env ruby require 'rubygems' require 'hpricot' require 'xml' require 'rexml/document' ITERATIONS = 3 NESTED_ITERATIONS = 5 def bm(name, filename, &block) text = File.open(filename).read length = text.length / 1024.0 / 1024.0 puts "#{filename}: #{name} (#{(length * 1024).round} kb)" for j in 0 .. NESTED_ITERATIONS s = Time.now.to_f for i in 0 .. ITERATIONS block.call(text) end timer = Time.now.to_f - s puts "\t#{length * ITERATIONS / timer} MB/s" end end def bm_suite(filenames) filenames.each do |filename| bm("LIBXML THROUGHPUT:", filename) do |text| XML::Document.file(filename) end bm("HPRICOT THROUGHPUT:", filename) do |text| Hpricot.XML(text) end bm("REXML THROUGHPUT:", filename) do |text| REXML::Document.new(text) end end end bm_suite("hamlet.xml") libxml-ruby-3.2.1/script/benchmark/sock_entries.xml0000644000004100000410000030124313760147770022502 0ustar www-datawww-data a0a5c490-b78e-11db-b2b3-0014c2c34555 http://saildataservice.concord.org/3/offering/1562/bundle/3693/1 libxml-ruby-3.2.1/LICENSE0000644000004100000410000000227513760147770015042 0ustar www-datawww-data Copyright (c) 2008-2013 Charlie Savage and contributors Copyright (c) 2002-2007 Sean Chittenden and contributors Copyright (c) 2001 Wai-Sun "Squidster" Chia Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.libxml-ruby-3.2.1/Rakefile0000644000004100000410000000465213760147770015503 0ustar www-datawww-data#!/usr/bin/env ruby require "rubygems" require "rake/extensiontask" require "rake/testtask" require "rubygems/package_task" require "rdoc/task" require "yaml" GEM_NAME = "libxml-ruby" SO_NAME = "libxml_ruby" # Read the spec file spec = Gem::Specification.load("#{GEM_NAME}.gemspec") task :default => [:test] # Setup compile tasks if RUBY_PLATFORM.match(/mswin32|mswin64|mingw32/) Rake::ExtensionTask.new do |ext| ext.gem_spec = spec ext.name = SO_NAME ext.ext_dir = "ext/libxml" ext.lib_dir = "lib/#{RUBY_VERSION.sub(/\.\d$/, '')}" ext.config_options << "--with-xml2-include=C:/msys64/mingw64/include/libxml2" end else Rake::ExtensionTask.new do |ext| ext.gem_spec = spec ext.name = SO_NAME ext.ext_dir = "ext/libxml" ext.lib_dir = "lib/#{RUBY_VERSION.sub(/\.\d$/, '')}" ext.config_options << "--with-xml2-include=/usr/include/libxml2" end end # Setup generic gem Gem::PackageTask.new(spec) do |pkg| pkg.package_dir = 'pkg' pkg.need_tar = false end # Setup Windows Gem if RUBY_PLATFORM.match(/mswin32|mswin64|mingw32/) binaries = (FileList['lib/**/*.so', 'lib/**/*dll']) # Windows specification win_spec = spec.clone win_spec.platform = Gem::Platform::CURRENT win_spec.files += binaries.to_a win_spec.instance_variable_set(:@cache_file, nil) # Unset extensions win_spec.extensions = nil # Rake task to build the windows package Gem::PackageTask.new(win_spec) do |pkg| pkg.package_dir = 'pkg' pkg.need_tar = false end end # RDoc Task desc 'Generate rdoc documentation' RDoc::Task.new("rdoc") do |rdoc| rdoc.rdoc_dir = 'rdoc' rdoc.title = 'LibXML' rdoc.generator = 'hanna' # Show source inline with line numbers rdoc.options << '--line-numbers' rdoc.options << '--charset=utf-8' # Make the readme file the start page for the generated html rdoc.main = 'README.rdoc' rdoc.rdoc_files.include('doc/*.rdoc', 'ext/**/libxml.c', 'ext/**/ruby_xml.c', 'ext/**/*.c', 'lib/**/*.rb', 'README.rdoc', 'HISTORY', 'LICENSE') end # Test Task Rake::TestTask.new do |t| t.libs << "test" t.test_files = FileList['test/test*.rb'] - ['test/test_suite.rb'] t.verbose = true endlibxml-ruby-3.2.1/lib/0000755000004100000410000000000013760147770014575 5ustar www-datawww-datalibxml-ruby-3.2.1/lib/libxml-ruby.rb0000644000004100000410000000126513760147770017374 0ustar www-datawww-data# encoding: UTF-8 # Load the C-based binding. begin RUBY_VERSION =~ /(\d+.\d+)/ require "#{$1}/libxml_ruby" rescue LoadError require "libxml_ruby" end # Load Ruby supporting code. require 'libxml/error' require 'libxml/parser' require 'libxml/document' require 'libxml/namespaces' require 'libxml/namespace' require 'libxml/node' require 'libxml/attributes' require 'libxml/attr' require 'libxml/attr_decl' require 'libxml/tree' require 'libxml/html_parser' require 'libxml/sax_parser' require 'libxml/sax_callbacks' #Schema Interface require 'libxml/schema' require 'libxml/schema/type' require 'libxml/schema/element' require 'libxml/schema/attribute' libxml-ruby-3.2.1/lib/xml/0000755000004100000410000000000013760147770015375 5ustar www-datawww-datalibxml-ruby-3.2.1/lib/xml/libxml.rb0000644000004100000410000000020313760147770017204 0ustar www-datawww-data# encoding: UTF-8 # This is here for backward compatibility. # # TODO: DEPRECATE! require 'libxml.rb' include LibXML libxml-ruby-3.2.1/lib/xml.rb0000644000004100000410000000072013760147770015721 0ustar www-datawww-data# encoding: UTF-8 # This file loads libxml and adds the LibXML namespace # to the toplevel for conveneience. The end result # is to have XML:: universally exposed. # # It is recommend that you only load this file for libs # that do not have their own namespace, eg. administrative # scripts, personal programs, etc. For other applications # require 'libxml' instead and include LibXML into your # app/libs namespace. require 'libxml' include LibXMLlibxml-ruby-3.2.1/lib/libxml/0000755000004100000410000000000013760147770016064 5ustar www-datawww-datalibxml-ruby-3.2.1/lib/libxml/schema/0000755000004100000410000000000013760147770017324 5ustar www-datawww-datalibxml-ruby-3.2.1/lib/libxml/schema/attribute.rb0000644000004100000410000000040513760147770021653 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class Schema::Attribute REQUIRED = 1 OPTIONAL = 2 def default node['default'] end def required? occurs == REQUIRED end end end end libxml-ruby-3.2.1/lib/libxml/schema/element.rb0000644000004100000410000000041413760147770021301 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class Schema::Element def required? !min_occurs.zero? end def array? max_occurs > 1 end def elements type.elements end end end end libxml-ruby-3.2.1/lib/libxml/schema/type.rb0000644000004100000410000000105613760147770020634 0ustar www-datawww-datamodule LibXML module XML class Schema::Type def kind_name Schema::Types.constants.find { |k| Schema::Types.const_get(k) == kind } end def annonymus_subtypes elements.select { |_, e| e.type.name.nil? } end def annonymus_subtypes_recursively(parent=nil) annonymus_subtypes.map do |element_name, e| [{[parent, element_name].compact.join('::') => e.type}, e.type.annonymus_subtypes_recursively(element_name)] end.flatten end end end end libxml-ruby-3.2.1/lib/libxml/attr.rb0000644000004100000410000000515713760147770017373 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class Attr include Enumerable # call-seq: # attr.child? -> (true|false) # # Returns whether this attribute has child attributes. # def child? not self.children.nil? end # call-seq: # attr.doc? -> (true|false) # # Determine whether this attribute is associated with an # XML::Document. def doc? not self.doc.nil? end # call-seq: # attr.last? -> (true|false) # # Determine whether this is the last attribute. def last? self.last.nil? end # call-seq: # attr.next? -> (true|false) # # Determine whether there is a next attribute. def next? not self.next.nil? end # call-seq: # attr.ns? -> (true|false) # # Determine whether this attribute has an associated # namespace. def ns? not self.ns.nil? end # call-seq: # attr.namespacess -> XML::Namespaces # # Returns this node's XML::Namespaces object, # which is used to access the namespaces # associated with this node. def namespaces @namespaces ||= XML::Namespaces.new(self) end # # call-seq: # attr.parent? -> (true|false) # # Determine whether this attribute has a parent. def parent? not self.parent.nil? end # call-seq: # attr.prev? -> (true|false) # # Determine whether there is a previous attribute. def prev? not self.prev.nil? end # Returns this node's type name def node_type_name if node_type == Node::ATTRIBUTE_NODE 'attribute' else raise(UnknownType, "Unknown node type: %n", node.node_type); end end # Iterates nodes and attributes def siblings(node, &blk) if n = node loop do blk.call(n) break unless n = n.next end end end def each_sibling(&blk) siblings(self,&blk) end alias :each_attr :each_sibling alias :each :each_sibling def to_h inject({}) do |h,a| h[a.name] = a.value h end end def to_a inject([]) do |ary,a| ary << [a.name, a.value] ary end end def to_s "#{name} = #{value}" end end end endlibxml-ruby-3.2.1/lib/libxml/document.rb0000644000004100000410000001577713760147770020250 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class Document # call-seq: # XML::Document.document(document) -> XML::Document # # Creates a new document based on the specified document. # # Parameters: # # document - A preparsed document. def self.document(value) Parser.document(value).parse end # call-seq: # XML::Document.file(path) -> XML::Document # XML::Document.file(path, :encoding => XML::Encoding::UTF_8, # :options => XML::Parser::Options::NOENT) -> XML::Document # # Creates a new document from the specified file or uri. # # You may provide an optional hash table to control how the # parsing is performed. Valid options are: # # encoding - The document encoding, defaults to nil. Valid values # are the encoding constants defined on XML::Encoding. # options - Parser options. Valid values are the constants defined on # XML::Parser::Options. Mutliple options can be combined # by using Bitwise OR (|). def self.file(value, options = {}) Parser.file(value, options).parse end # call-seq: # XML::Document.io(io) -> XML::Document # XML::Document.io(io, :encoding => XML::Encoding::UTF_8, # :options => XML::Parser::Options::NOENT # :base_uri="http://libxml.org") -> XML::Document # # Creates a new document from the specified io object. # # Parameters: # # io - io object that contains the xml to parser # base_uri - The base url for the parsed document. # encoding - The document encoding, defaults to nil. Valid values # are the encoding constants defined on XML::Encoding. # options - Parser options. Valid values are the constants defined on # XML::Parser::Options. Mutliple options can be combined # by using Bitwise OR (|). def self.io(value, options = {}) Parser.io(value, options).parse end # call-seq: # XML::Document.string(string) -> XML::Document # XML::Document.string(string, :encoding => XML::Encoding::UTF_8, # :options => XML::Parser::Options::NOENT # :base_uri="http://libxml.org") -> XML::Document # # Creates a new document from the specified string. # # You may provide an optional hash table to control how the # parsing is performed. Valid options are: # # base_uri - The base url for the parsed document. # encoding - The document encoding, defaults to nil. Valid values # are the encoding constants defined on XML::Encoding. # options - Parser options. Valid values are the constants defined on # XML::Parser::Options. Mutliple options can be combined # by using Bitwise OR (|). def self.string(value, options = {}) Parser.string(value, options).parse end # Returns a new XML::XPathContext for the document. # # call-seq: # document.context(namespaces=nil) -> XPath::Context # # Namespaces is an optional array of XML::NS objects def context(nslist = nil) context = XPath::Context.new(self) context.node = self.root context.register_namespaces_from_node(self.root) context.register_namespaces(nslist) if nslist context end # Return the nodes matching the specified xpath expression, # optionally using the specified namespace. For more # information about working with namespaces, please refer # to the XML::XPath documentation. # # call-seq: # document.find(xpath, nslist=nil) -> XML::XPath::Object # # Parameters: # * xpath - The xpath expression as a string # * namespaces - An optional list of namespaces (see XML::XPath for information). # # document.find('/foo', 'xlink:http://www.w3.org/1999/xlink') # # IMPORTANT - The returned XML::Node::Set must be freed before # its associated document. In a running Ruby program this will # happen automatically via Ruby's mark and sweep garbage collector. # However, if the program exits, Ruby does not guarantee the order # in which objects are freed # (see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/17700). # As a result, the associated document may be freed before the node # list, which will cause a segmentation fault. # To avoid this, use the following (non-ruby like) coding style: # # nodes = doc.find('/header') # nodes.each do |node| # ... do stuff ... # end # # nodes = nil # GC.start def find(xpath, nslist = nil) self.context(nslist).find(xpath) end # Return the first node matching the specified xpath expression. # For more information, please refer to the documentation # for XML::Document#find. def find_first(xpath, nslist = nil) find(xpath, nslist).first end # Returns this node's type name def node_type_name case node_type when XML::Node::DOCUMENT_NODE 'document_xml' when XML::Node::DOCB_DOCUMENT_NODE 'document_docbook' when XML::Node::HTML_DOCUMENT_NODE 'document_html' else raise(UnknownType, "Unknown node type: %n", node.node_type); end end # :enddoc: # Specifies if this is an document node def document? node_type == XML::Node::DOCUMENT_NODE end # Specifies if this is an docbook node def docbook_doc? node_type == XML::Node::DOCB_DOCUMENT_NODE end # Specifies if this is an html node def html_doc? node_type == XML::Node::HTML_DOCUMENT_NODE end def dump warn('Document#dump is deprecated. Use Document#to_s instead.') self.to_s end def format_dump warn('Document#format_dump is deprecated. Use Document#to_s instead.') self.to_s end def debug_dump warn('Document#debug_dump is deprecated. Use Document#debug instead.') self.debug end def debug_dump_head warn('Document#debug_dump_head is deprecated. Use Document#debug instead.') self.debug end def debug_format_dump warn('Document#debug_format_dump is deprecated. Use Document#to_s instead.') self.to_s end def reader warn('Document#reader is deprecated. Use XML::Reader.document(self) instead.') XML::Reader.document(self) end end end end libxml-ruby-3.2.1/lib/libxml/namespace.rb0000644000004100000410000000257713760147770020360 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class Namespace include Comparable include Enumerable # call-seq: # namespace1 <=> namespace2 # # Compares two namespace objects. Namespace objects are # considered equal if their prefixes and hrefs are the same. def <=>(other) if self.prefix.nil? and other.prefix.nil? self.href <=> other.href elsif self.prefix.nil? -1 elsif other.prefix.nil? 1 else self.prefix <=> other.prefix end end # call-seq: # namespace.each {|ns| .. } # # libxml stores namespaces in memory as a linked list. # Use the each method to iterate over the list. Note # the first namespace in the loop is the current namespace. # # Usage: # namespace.each do |ns| # .. # end def each ns = self while ns yield ns ns = ns.next end end # call-seq: # namespace.to_s -> "string" # # Returns the string represenation of a namespace. # # Usage: # namespace.to_s def to_s if self.prefix "#{self.prefix}:#{self.href}" else self.href end end end end endlibxml-ruby-3.2.1/lib/libxml/schema.rb0000644000004100000410000000374213760147770017657 0ustar www-datawww-datamodule LibXML module XML class Schema module Types XML_SCHEMA_TYPE_BASIC = 1 # A built-in datatype XML_SCHEMA_TYPE_ANY = 2 XML_SCHEMA_TYPE_FACET = 3 XML_SCHEMA_TYPE_SIMPLE = 4 XML_SCHEMA_TYPE_COMPLEX = 5 XML_SCHEMA_TYPE_SEQUENCE = 6 XML_SCHEMA_TYPE_CHOICE = 7 XML_SCHEMA_TYPE_ALL = 8 XML_SCHEMA_TYPE_SIMPLE_CONTENT = 9 XML_SCHEMA_TYPE_COMPLEX_CONTENT = 10 XML_SCHEMA_TYPE_UR = 11 XML_SCHEMA_TYPE_RESTRICTION = 12 XML_SCHEMA_TYPE_EXTENSION = 13 XML_SCHEMA_TYPE_ELEMENT = 14 XML_SCHEMA_TYPE_ATTRIBUTE = 15 XML_SCHEMA_TYPE_ATTRIBUTEGROUP = 16 XML_SCHEMA_TYPE_GROUP = 17 XML_SCHEMA_TYPE_NOTATION = 18 XML_SCHEMA_TYPE_LIST = 19 XML_SCHEMA_TYPE_UNION = 20 XML_SCHEMA_TYPE_ANY_ATTRIBUTE = 21 XML_SCHEMA_TYPE_IDC_UNIQUE = 22 XML_SCHEMA_TYPE_IDC_KEY = 23 XML_SCHEMA_TYPE_IDC_KEYREF = 24 XML_SCHEMA_TYPE_PARTICLE = 25 XML_SCHEMA_TYPE_ATTRIBUTE_USE = 26 XML_SCHEMA_FACET_MININCLUSIVE = 1000 XML_SCHEMA_FACET_MINEXCLUSIVE = 1001 XML_SCHEMA_FACET_MAXINCLUSIVE = 1002 XML_SCHEMA_FACET_MAXEXCLUSIVE = 1003 XML_SCHEMA_FACET_TOTALDIGITS = 1004 XML_SCHEMA_FACET_FRACTIONDIGITS = 1005 XML_SCHEMA_FACET_PATTERN = 1006 XML_SCHEMA_FACET_ENUMERATION = 1007 XML_SCHEMA_FACET_WHITESPACE = 1008 XML_SCHEMA_FACET_LENGTH = 1009 XML_SCHEMA_FACET_MAXLENGTH = 1010 XML_SCHEMA_FACET_MINLENGTH = 1011 XML_SCHEMA_EXTRA_QNAMEREF = 2000 XML_SCHEMA_EXTRA_ATTR_USE_PROHIB = 2001 end end end endlibxml-ruby-3.2.1/lib/libxml/error.rb0000644000004100000410000000506413760147770017547 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class Error # Create mapping from domain constant value to keys DOMAIN_CODE_MAP = [:NO_ERROR, :PARSER, :TREE, :NAMESPACE, :DTD, :HTML, :MEMORY, :OUTPUT, :IO, :FTP, :HTTP, :XINCLUDE, :XPATH, :XPOINTER, :REGEXP, :DATATYPE, :SCHEMASP, :SCHEMASV, :RELAXNGP, :RELAXNGV, :CATALOG, :C14N, :XSLT, :VALID, :CHECK, :WRITER, :MODULE, :I18N, :SCHEMATRONV].inject(Hash.new) do |hash, code| if const_defined?(code) hash[const_get(code)] = code.to_s end hash end # Create mapping from domain constant value to keys ERROR_CODE_MAP = Hash.new.tap do |map| (constants - DOMAIN_CODE_MAP.values - #Domains [:NONE, :WARNING, :ERROR, :FATAL] # Levels ).each do |code| map[const_get(code)] = code.to_s end end # Verbose error handler VERBOSE_HANDLER = lambda do |error| STDERR << error.to_s << "\n" STDERR.flush end # Quiet error handler QUIET_HANDLER = lambda do |error| end def ==(other) eql?(other) end def eql?(other) self.code == other.code and self.domain == other.domain and self.message == other.message and self.level == other.level and self.file == other.file and self.line == other.line and self.str1 == other.str1 and self.str2 == other.str2 and self.str3 == other.str3 and self.int1 == other.int1 and self.int2 == other.int2 and self.ctxt == other.ctxt and self.node == other.node rescue false end def level_to_s case self.level when NONE '' when WARNING 'Warning:' when ERROR 'Error:' when FATAL 'Fatal error:' end end def domain_to_s DOMAIN_CODE_MAP[self.domain] end def code_to_s ERROR_CODE_MAP[self.code] end def to_s msg = super msg = msg ? msg.strip: '' if self.line sprintf("%s %s at %s:%d.", self.level_to_s, msg, self.file, self.line) else sprintf("%s %s.", self.level_to_s, msg) end end end end end LibXML::XML::Error.set_handler(&LibXML::XML::Error::VERBOSE_HANDLER) libxml-ruby-3.2.1/lib/libxml/attributes.rb0000644000004100000410000000033713760147770020602 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class Attributes def to_h inject({}) do |hash, attr| hash[attr.name] = attr.value hash end end end end endlibxml-ruby-3.2.1/lib/libxml/sax_callbacks.rb0000644000004100000410000001241513760147770021206 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class SaxParser module Callbacks # Called for a CDATA block event. def on_cdata_block(cdata) end # Called for a characters event. def on_characters(chars) end # Called for a comment event. def on_comment(msg) end # Called for a end document event. def on_end_document end # Called for a end element event. def on_end_element_ns(name, prefix, uri) end # Called for parser errors. def on_error(msg) end # Called for an external subset event. def on_external_subset(name, external_id, system_id) end # Called for an external subset notification event. def on_has_external_subset end # Called for an internal subset notification event. def on_has_internal_subset end # Called for an internal subset event. def on_internal_subset(name, external_id, system_id) end # Called for 'is standalone' event. def on_is_standalone end # Called for an processing instruction event. def on_processing_instruction(target, data) end # Called for a reference event. def on_reference(name) end # Called for a start document event. def on_start_document end # Called for a start element event. def on_start_element_ns(name, attributes, prefix, uri, namespaces) end end module VerboseCallbacks # Called for a CDATA block event. def on_cdata_block(cdata) STDOUT << "on_cdata_block" << "\n" << " cdata " << cdata << "\n" STDOUT.flush end # Called for a characters event. def on_characters(chars) STDOUT << "on_characters" << "\n" << " chars " << chars << "\n" STDOUT.flush end # Called for a comment event. def on_comment(comment) STDOUT << "on_comment" << "\n" << " comment: " << comment << "\n" STDOUT.flush end # Called for a end document event. def on_end_document STDOUT << "on_end_document\n" STDOUT.flush end # Called for a end element event. def on_end_element_ns(name, prefix, uri) STDOUT << "on_end_element_ns" << "\n" << " name: " << name << "\n" << " prefix: " << prefix << "\n" << " uri: " << uri << "\n" STDOUT.flush end # Called for parser errors. def on_error(error) STDOUT << "on_error" << "\n" " error " << error << "\n" STDOUT.flush end # Called for an external subset event. def on_external_subset(name, external_id, system_id) STDOUT << "on_external_subset" << "\n" " external_id " << external_id << "\n" << " system_id " << system_id << "\n" STDOUT.flush end # Called for an external subset notification event. def on_has_external_subset STDOUT << "on_has_internal_subset\n" STDOUT.flush end # Called for an internal subset notification event. def on_has_internal_subset STDOUT << "on_has_internal_subset\n" STDOUT.flush end # Called for an internal subset event. def on_internal_subset(name, external_id, system_id) STDOUT << "on_internal_subset" << "\n" " external_id " << external_id << "\n" << " system_id " << system_id << "\n" STDOUT.flush end # Called for 'is standalone' event. def on_is_standalone STDOUT << "on_is_standalone\n" STDOUT.flush end # Called for an processing instruction event. def on_processing_instruction(target, data) STDOUT << "on_characters" << "\n" " target: " << target << "\n" << " data: " << data << "\n" STDOUT.flush end # Called for a reference event. def on_reference(name) STDOUT << "on_reference:" << "\n" << " name:" << name << "\n" STDOUT.flush end # Called for a start document event. def on_start_document STDOUT << "on_start_document\n" STDOUT.flush end # Called for a start element event. def on_start_element_ns(name, attributes, prefix, uri, namespaces) STDOUT << "on_start_element_ns" << "\n" << " name: " << name << "\n" << " attr: " << (attributes || Hash.new).inspect << "\n" << " prefix: " << prefix << "\n" << " uri: " << uri << "\n" << " ns_defs: " << (namespaces || Hash.new).inspect << "\n" STDOUT.flush end end end end endlibxml-ruby-3.2.1/lib/libxml/tree.rb0000644000004100000410000000177013760147770017355 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class Tree # :nodoc: ELEMENT_NODE = Node::ELEMENT_NODE ATTRIBUTE_NODE = Node::ATTRIBUTE_NODE TEXT_NODE = Node::TEXT_NODE CDATA_SECTION_NODE = Node::CDATA_SECTION_NODE ENTITY_REF_NODE = Node::ENTITY_REF_NODE ENTITY_NODE = Node::ENTITY_NODE PI_NODE = Node::PI_NODE COMMENT_NODE = Node::COMMENT_NODE DOCUMENT_NODE = Node::DOCUMENT_NODE DOCUMENT_TYPE_NODE = Node::DOCUMENT_TYPE_NODE DOCUMENT_FRAG_NODE = Node::DOCUMENT_FRAG_NODE NOTATION_NODE = Node::NOTATION_NODE HTML_DOCUMENT_NODE = Node::HTML_DOCUMENT_NODE DTD_NODE = Node::DTD_NODE ELEMENT_DECL = Node::ELEMENT_DECL ATTRIBUTE_DECL = Node::ATTRIBUTE_DECL ENTITY_DECL = Node::ENTITY_DECL NAMESPACE_DECL = Node::NAMESPACE_DECL XINCLUDE_START = Node::XINCLUDE_START XINCLUDE_END = Node::XINCLUDE_END DOCB_DOCUMENT_NODE = Node::DOCB_DOCUMENT_NODE end end endlibxml-ruby-3.2.1/lib/libxml/node.rb0000644000004100000410000002070613760147770017343 0ustar www-datawww-data# encoding: UTF-8 require 'stringio' module LibXML module XML class Node # Determines whether this node has attributes def attributes? attributes.length > 0 end # Create a shallow copy of the node. To create # a deep copy call Node#copy(true) def clone copy(false) end # call-seq: # node.inner_xml -> "string" # node.inner_xml(:indent => true, :encoding => 'UTF-8', :level => 0) -> "string" # # Converts a node's children to a string representation. To include # the node, use XML::Node#to_s. For more information about # the supported options, see XML::Node#to_s. def inner_xml(options = Hash.new) io = nil self.each do |node| xml = node.to_s(options) # Create the string IO here since we now know the encoding io = create_string_io(xml) unless io io << xml end io ? io.string : nil end # :call-seq: # node.dup -> XML::Node # # Create a shallow copy of the node. To create # a deep copy call Node#copy(true) def dup copy(false) end # call-seq: # node.context(namespaces=nil) -> XPath::Context # # Returns a new XML::XPathContext for the current node. # # Namespaces is an optional array of XML::NS objects def context(nslist = nil) if not self.doc raise(TypeError, "A node must belong to a document before a xpath context can be created") end context = XPath::Context.new(self.doc) context.node = self context.register_namespaces_from_node(self) context.register_namespaces_from_node(self.doc.root) context.register_namespaces(nslist) if nslist context end # call-seq: # node.find(namespaces=nil) -> XPath::XPathObject # # Return nodes matching the specified xpath expression. # For more information, please refer to the documentation # for XML::Document#find. # # Namespaces is an optional array of XML::NS objects def find(xpath, nslist = nil) self.context(nslist).find(xpath) end # call-seq: # node.find_first(namespaces=nil) -> XML::Node # # Return the first node matching the specified xpath expression. # For more information, please refer to the documentation # for the #find method. def find_first(xpath, nslist = nil) find(xpath, nslist).first end # call-seq: # node.namespacess -> XML::Namespaces # # Returns this node's XML::Namespaces object, # which is used to access the namespaces # associated with this node. def namespaces @namespaces ||= XML::Namespaces.new(self) end # ------- Traversal ---------------- # Iterates over this node's attributes. # # doc = XML::Document.new('model/books.xml') # doc.root.each_attr {|attr| puts attr} def each_attr attributes.each do |attr| yield(attr) end end # Iterates over this node's child elements (nodes # that have a node_type == ELEMENT_NODE). # # doc = XML::Document.new('model/books.xml') # doc.root.each_element {|element| puts element} def each_element each do |node| yield(node) if node.node_type == ELEMENT_NODE end end # Determines whether this node has a parent node def parent? not parent.nil? end # Determines whether this node has a first node def first? not first.nil? end # Returns this node's children as an array. def children entries end # Determines whether this node has a next node def next? not self.next.nil? end # Determines whether this node has a previous node def prev? not prev.nil? end # Determines whether this node has a last node def last? not last.nil? end # ------- Node Types ---------------- # Returns this node's type name def node_type_name case node_type # Most common choices first when ATTRIBUTE_NODE 'attribute' when DOCUMENT_NODE 'document_xml' when ELEMENT_NODE 'element' when TEXT_NODE 'text' # Now the rest when ATTRIBUTE_DECL 'attribute_decl' when CDATA_SECTION_NODE 'cdata' when COMMENT_NODE 'comment' when DOCB_DOCUMENT_NODE 'document_docbook' when DOCUMENT_FRAG_NODE 'fragment' when DOCUMENT_TYPE_NODE 'doctype' when DTD_NODE 'dtd' when ELEMENT_DECL 'elem_decl' when ENTITY_DECL 'entity_decl' when ENTITY_NODE 'entity' when ENTITY_REF_NODE 'entity_ref' when HTML_DOCUMENT_NODE 'document_html' when NAMESPACE_DECL 'namespace' when NOTATION_NODE 'notation' when PI_NODE 'pi' when XINCLUDE_START 'xinclude_start' when XINCLUDE_END 'xinclude_end' else raise(UnknownType, "Unknown node type: %n", node.node_type); end end # Specifies if this is an attribute node def attribute? node_type == ATTRIBUTE_NODE end # Specifies if this is an attribute declaration node def attribute_decl? node_type == ATTRIBUTE_DECL end # Specifies if this is an CDATA node def cdata? node_type == CDATA_SECTION_NODE end # Specifies if this is an comment node def comment? node_type == COMMENT_NODE end # Specifies if this is an docbook node def docbook_doc? node_type == DOCB_DOCUMENT_NODE end # Specifies if this is an doctype node def doctype? node_type == DOCUMENT_TYPE_NODE end # Specifies if this is an document node def document? node_type == DOCUMENT_NODE end # Specifies if this is an DTD node def dtd? node_type == DTD_NODE end # Specifies if this is an element node def element? node_type == ELEMENT_NODE end # Specifies if this is an entity node def entity? node_type == ENTITY_NODE end # Specifies if this is an element declaration node def element_decl? node_type == ELEMENT_DECL end # Specifies if this is an entity reference node def entity_ref? node_type == ENTITY_REF_NODE end # Specifies if this is a fragment node def fragment? node_type == DOCUMENT_FRAG_NODE end # Specifies if this is a html document node def html_doc? node_type == HTML_DOCUMENT_NODE end # Specifies if this is a namespace node (not if it # has a namepsace) def namespace? node_type == NAMESPACE_DECL end # Specifies if this is a notation node def notation? node_type == NOTATION_NODE end # Specifies if this is a processiong instruction node def pi? node_type == PI_NODE end # Specifies if this is a text node def text? node_type == TEXT_NODE end # Specifies if this is an xinclude end node def xinclude_end? node_type == XINCLUDE_END end # Specifies if this is an xinclude start node def xinclude_start? node_type == XINCLUDE_START end alias :child? :first? alias :children? :first? alias :child :first alias :each_child :each private def create_string_io(xml) result = StringIO.new("") if defined?(::Encoding) result.set_encoding(xml.encoding) end result end end end end libxml-ruby-3.2.1/lib/libxml/hpricot.rb0000644000004100000410000000365113760147770020066 0ustar www-datawww-data# encoding: UTF-8 ## Provide hpricot API for libxml. Provided by Michael Guterl, ## inspired by http://thebogles.com/blog/an-hpricot-style-interface-to-libxml # #class String # def to_libxml_doc # xp = XML::Parser.new # xp.string = self # xp.parse # end #end # #module LibXML # module XML # class Document # alias :search :find # end # # class Node # # find the child node with the given xpath # def at(xpath) # self.find_first(xpath) # end # # # find the array of child nodes matching the given xpath # def search(xpath) # results = self.find(xpath).to_a # if block_given? # results.each do |result| # yield result # end # end # return results # end # # def /(xpath) # search(xpath) # end # # # return the inner contents of this node as a string # def inner_xml # child.to_s # end # # # alias for inner_xml # def inner_html # inner_xml # end # # # return this node and its contents as an xml string # def to_xml # self.to_s # end # # # alias for path # def xpath # self.path # end # # def find_with_default_ns(xpath_expr, namespace=nil) # find_base(xpath_expr, namespace || default_namespaces) # end # # def find_first_with_default_ns(xpath_expr, namespace=nil) # find_first_base(xpath_expr, namespace || default_namespaces) # end # ## alias_method :find_base, :find unless method_defined?(:find_base) ## alias_method :find, :find_with_default_ns ## alias_method :find_first_base, :find_first unless method_defined?(:find_first_base) ## alias_method :find_first, :find_first_with_default_ns ## alias :child? :first? ## alias :children? :first? ## alias :child :first # end # end #endlibxml-ruby-3.2.1/lib/libxml/html_parser.rb0000644000004100000410000001021013760147770020723 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class HTMLParser # call-seq: # XML::HTMLParser.file(path) -> XML::HTMLParser # XML::HTMLParser.file(path, :encoding => XML::Encoding::UTF_8, # :options => XML::HTMLParser::Options::NOENT) -> XML::HTMLParser # # Creates a new parser by parsing the specified file or uri. # # You may provide an optional hash table to control how the # parsing is performed. Valid options are: # # encoding - The document encoding, defaults to nil. Valid values # are the encoding constants defined on XML::Encoding. # options - Parser options. Valid values are the constants defined on # XML::HTMLParser::Options. Mutliple options can be combined # by using Bitwise OR (|). def self.file(path, options = {}) context = XML::HTMLParser::Context.file(path) context.encoding = options[:encoding] if options[:encoding] context.options = options[:options] if options[:options] self.new(context) end # call-seq: # XML::HTMLParser.io(io) -> XML::HTMLParser # XML::HTMLParser.io(io, :encoding => XML::Encoding::UTF_8, # :options => XML::HTMLParser::Options::NOENT # :base_uri="http://libxml.org") -> XML::HTMLParser # # Creates a new reader by parsing the specified io object. # # Parameters: # # io - io object that contains the xml to parser # base_uri - The base url for the parsed document. # encoding - The document encoding, defaults to nil. Valid values # are the encoding constants defined on XML::Encoding. # options - Parser options. Valid values are the constants defined on # XML::HTMLParser::Options. Mutliple options can be combined # by using Bitwise OR (|). def self.io(io, options = {}) context = XML::HTMLParser::Context.io(io) context.base_uri = options[:base_uri] if options[:base_uri] context.encoding = options[:encoding] if options[:encoding] context.options = options[:options] if options[:options] self.new(context) end # call-seq: # XML::HTMLParser.string(string) # XML::HTMLParser.string(string, :encoding => XML::Encoding::UTF_8, # :options => XML::HTMLParser::Options::NOENT # :base_uri="http://libxml.org") -> XML::HTMLParser # # Creates a new parser by parsing the specified string. # # You may provide an optional hash table to control how the # parsing is performed. Valid options are: # # base_uri - The base url for the parsed document. # encoding - The document encoding, defaults to nil. Valid values # are the encoding constants defined on XML::Encoding. # options - Parser options. Valid values are the constants defined on # XML::HTMLParser::Options. Mutliple options can be combined # by using Bitwise OR (|). def self.string(string, options = {}) context = XML::HTMLParser::Context.string(string) context.base_uri = options[:base_uri] if options[:base_uri] context.encoding = options[:encoding] if options[:encoding] context.options = options[:options] if options[:options] self.new(context) end # :enddoc: def file=(value) warn("XML::HTMLParser#file is deprecated. Use XML::HTMLParser.file instead") @context = XML::HTMLParser::Context.file(value) end def io=(value) warn("XML::HTMLParser#io is deprecated. Use XML::HTMLParser.io instead") @context = XML::HTMLParser::Context.io(value) end def string=(value) warn("XML::HTMLParser#string is deprecated. Use XML::HTMLParser.string instead") @context = XML::HTMLParser::Context.string(value) end end end end libxml-ruby-3.2.1/lib/libxml/attr_decl.rb0000644000004100000410000000361713760147770020361 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class AttrDecl include Enumerable # call-seq: # attr_decl.child -> nil # # Obtain this attribute declaration's child attribute(s). # It will always be nil. def child nil end # call-seq: # attr_decl.child? -> (true|false) # # Returns whether this attribute declaration has child attributes. # def child? not self.children.nil? end # call-seq: # attr_decl.doc? -> (true|false) # # Determine whether this attribute declaration is associated with an # XML::Document. def doc? not self.doc.nil? end # call-seq: # attr_decl.next? -> (true|false) # # Determine whether there is a next attribute declaration. def next? not self.next.nil? end # call-seq: # attr_decl.parent? -> (true|false) # # Determine whether this attribute declaration has a parent . def parent? not self.parent.nil? end # call-seq: # attr_decl.prev? -> (true|false) # # Determine whether there is a previous attribute declaration. def prev? not self.prev.nil? end # call-seq: # attr_decl.node_type_name -> 'attribute declaration' # # Returns this attribute declaration's node type name. def node_type_name if node_type == Node::ATTRIBUTE_DECL 'attribute declaration' else raise(UnknownType, "Unknown node type: %n", node.node_type); end end # call-seq: # attr_decl.to_s -> string # # Returns a string representation of this attribute declaration. def to_s "#{name} = #{value}" end end end end libxml-ruby-3.2.1/lib/libxml/parser.rb0000644000004100000410000001013213760147770017702 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class Parser # call-seq: # XML::Parser.document(document) -> XML::Parser # # Creates a new parser for the specified document. # # Parameters: # # document - A preparsed document. def self.document(doc) context = XML::Parser::Context.document(doc) self.new(context) end # call-seq: # XML::Parser.file(path) -> XML::Parser # XML::Parser.file(path, :encoding => XML::Encoding::UTF_8, # :options => XML::Parser::Options::NOENT) -> XML::Parser # # Creates a new parser for the specified file or uri. # # You may provide an optional hash table to control how the # parsing is performed. Valid options are: # # encoding - The document encoding, defaults to nil. Valid values # are the encoding constants defined on XML::Encoding. # options - Parser options. Valid values are the constants defined on # XML::Parser::Options. Mutliple options can be combined # by using Bitwise OR (|). def self.file(path, options = {}) context = XML::Parser::Context.file(path) context.encoding = options[:encoding] if options[:encoding] context.options = options[:options] if options[:options] self.new(context) end # call-seq: # XML::Parser.io(io) -> XML::Parser # XML::Parser.io(io, :encoding => XML::Encoding::UTF_8, # :options => XML::Parser::Options::NOENT # :base_uri="http://libxml.org") -> XML::Parser # # Creates a new parser for the specified io object. # # Parameters: # # io - io object that contains the xml to parser # base_uri - The base url for the parsed document. # encoding - The document encoding, defaults to nil. Valid values # are the encoding constants defined on XML::Encoding. # options - Parser options. Valid values are the constants defined on # XML::Parser::Options. Mutliple options can be combined # by using Bitwise OR (|). def self.io(io, options = {}) context = XML::Parser::Context.io(io) context.base_uri = options[:base_uri] if options[:base_uri] context.encoding = options[:encoding] if options[:encoding] context.options = options[:options] if options[:options] self.new(context) end # call-seq: # XML::Parser.string(string) # XML::Parser.string(string, :encoding => XML::Encoding::UTF_8, # :options => XML::Parser::Options::NOENT # :base_uri="http://libxml.org") -> XML::Parser # # Creates a new parser by parsing the specified string. # # You may provide an optional hash table to control how the # parsing is performed. Valid options are: # # base_uri - The base url for the parsed document. # encoding - The document encoding, defaults to nil. Valid values # are the encoding constants defined on XML::Encoding. # options - Parser options. Valid values are the constants defined on # XML::Parser::Options. Mutliple options can be combined # by using Bitwise OR (|). def self.string(string, options = {}) context = XML::Parser::Context.string(string) context.base_uri = options[:base_uri] if options[:base_uri] context.encoding = options[:encoding] if options[:encoding] context.options = options[:options] if options[:options] self.new(context) end def self.register_error_handler(proc) warn('Parser.register_error_handler is deprecated. Use Error.set_handler instead') if proc.nil? Error.reset_handler else Error.set_handler(&proc) end end end end endlibxml-ruby-3.2.1/lib/libxml/namespaces.rb0000644000004100000410000000232013760147770020525 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class Namespaces # call-seq: # namespace.default -> XML::Namespace # # Returns the default namespace for this node or nil. # # Usage: # doc = XML::Document.string('') # ns = doc.root.namespaces.default_namespace # assert_equal(ns.href, 'http://schemas.xmlsoap.org/soap/envelope/') def default find_by_prefix(nil) end # call-seq: # namespace.default_prefix = "string" # # Assigns a name (prefix) to the default namespace. # This makes it much easier to perform XML::XPath # searches. # # Usage: # doc = XML::Document.string('') # doc.root.namespaces.default_prefix = 'soap' # node = doc.root.find_first('soap:Envelope') def default_prefix=(prefix) # Find default prefix ns = find_by_prefix(nil) raise(ArgumentError, "No default namespace was found") unless ns Namespace.new(self.node, prefix, ns.href) end end end endlibxml-ruby-3.2.1/lib/libxml/sax_parser.rb0000644000004100000410000000231613760147770020562 0ustar www-datawww-data# encoding: UTF-8 module LibXML module XML class SaxParser # call-seq: # XML::SaxParser.file(path) -> XML::SaxParser # # Creates a new parser by parsing the specified file or uri. def self.file(path) context = XML::Parser::Context.file(path) self.new(context) end # call-seq: # XML::SaxParser.io(io) -> XML::SaxParser # XML::SaxParser.io(io, :encoding => XML::Encoding::UTF_8) -> XML::SaxParser # # Creates a new reader by parsing the specified io object. # # Parameters: # # encoding - The document encoding, defaults to nil. Valid values # are the encoding constants defined on XML::Encoding. def self.io(io, options = {}) context = XML::Parser::Context.io(io) context.encoding = options[:encoding] if options[:encoding] self.new(context) end # call-seq: # XML::SaxParser.string(string) # # Creates a new parser by parsing the specified string. def self.string(string) context = XML::Parser::Context.string(string) self.new(context) end end end endlibxml-ruby-3.2.1/lib/libxml.rb0000644000004100000410000000014513760147770016411 0ustar www-datawww-data# encoding: UTF-8 # # This include is deprecated, use libxml-ruby instead! require 'libxml-ruby'libxml-ruby-3.2.1/README.rdoc0000644000004100000410000002143113760147770015636 0ustar www-datawww-data= LibXML Ruby == Overview The libxml gem provides Ruby language bindings for GNOME's Libxml2 XML toolkit. It is free software, released under the MIT License. We think libxml-ruby is the best XML library for Ruby because: * Speed - Its much faster than REXML and Hpricot * Features - It provides an amazing number of featues * Conformance - It passes all 1800+ tests from the OASIS XML Tests Suite == Requirements libxml-ruby requires Ruby 1.8.7 or higher. It depends on libxml2 to function properly. libxml2, in turn, depends on: * libm (math routines: very standard) * libz (zlib) * libiconv If you are running Linux or Unix you'll need a C compiler so the extension can be compiled when it is installed. If you are running Windows, then install the x64-mingw32 gem or build it yourself using Devkit[http://rubyinstaller.org/add-ons/devkit/] or msys2[https://msys2.github.io/]. == Installation The easiest way to install libxml-ruby is via RubyGems. To install: gem install libxml-ruby If the extension compile process cannot find libxml2, you may need to indicate the location of the libxml2 configuration utility as it is used to find the required header and include files. (If you need to indicate a location for the libxml2 library or header files different than reported by xml2-config, see the additional configuration options.) This may be done with RubyGems: gem install libxml-ruby -- --with-xml2-dir=/path/to/xml2-config Or bundler: bundle config build.libxml-ruby --with-xml2-config=/path/to/xml2-config bundle install libxml-ruby If you are running Windows, then install the libxml-ruby-x64-mingw32 gem. The gem includes prebuilt extensions for Ruby 2.3. These extensions are built using MinGW64 and libxml2 version 2.9.3, iconv version 1.14 and zlib version 1.2.8. Note these binaries are available in the lib\\libs directory. To use them, put them on your PATH. The gem also includes a Microsoft VC++ 2012 solution and XCode 5 project - these are very useful for debugging. libxml-ruby's source codes lives on GitHub[https://github.com/xml4r/libxml-ruby]. == Getting Started Using libxml is easy. First decide what parser you want to use: * Generally you'll want to use the LibXML::XML::Parser which provides a tree based API. * For larger documents that don't fit into memory, or if you prefer an input based API, use the LibXML::XML::Reader. * To parse HTML files use LibXML::XML::HTMLParser. * If you are masochistic, then use the LibXML::XML::SaxParser, which provides a callback API. Once you have chosen a parser, choose a datasource. Libxml can parse files, strings, URIs and IO streams. For each data source you can specify an LibXML::XML::Encoding, a base uri and various parser options. For more information, refer the LibXML::XML::Parser.document, LibXML::XML::Parser.file, LibXML::XML::Parser.io or LibXML:::XML::Parser.string methods (the same methods are defined on all four parser classes). == Advanced Functionality Beyond the basics of parsing and processing XML and HTML documents, libxml provides a wealth of additional functionality. Most commonly, you'll want to use its LibXML::XML::XPath support, which makes it easy to find data inside an XML document. Although not as popular, LibXML::XML::XPointer provides another API for finding data inside an XML document. Often times you'll need to validate data before processing it. For example, if you accept user generated content submitted over the Web, you'll want to verify that it does not contain malicious code such as embedded scripts. This can be done using libxml's powerful set of validators: * DTDs (LibXML::XML::Dtd) * Relax Schemas (LibXML::XML::RelaxNG) * XML Schema (LibXML::XML::Schema) Finally, if you'd like to use XSL Transformations to process data, then install the {libxslt gem}[https://github.com/xml4r/libxslt-rubygem]. == Usage For information about using libxml-ruby please refer to its documentation[http://xml4r.github.io/libxml-ruby]. Some tutorials are also available[https://github.com/xml4r/libxml-ruby/wiki]. All libxml classes are in the LibXML::XML module. The easiest way to use libxml is to require 'xml'. This will mixin the LibXML module into the global namespace, allowing you to write code like this: require 'xml' document = XML::Document.new However, when creating an application or library you plan to redistribute, it is best to not add the LibXML module to the global namespace, in which case you can either write your code like this: require 'libxml' document = LibXML::XML::Document.new Or you can utilize a namespace for your own work and include LibXML into it. For example: require 'libxml' module MyApplication include LibXML class MyClass def some_method document = XML::Document.new end end end For simplicity's sake, the documentation uses the xml module in its examples. == Threading libxml-ruby fully supports native, background Ruby threads. This of course only applies to Ruby 1.9.x and higher since earlier versions of Ruby do not support native threads. == Tests To run tests you first need to build the shared libary: rake compile Once you have build the shared libary, you can then run tests using rake: rake test +Travis build status: {Build Status}[https://travis-ci.org/xml4r/libxml-ruby] == Performance In addition to being feature rich and conformation, the main reason people use libxml-ruby is for performance. Here are the results of a couple simple benchmarks recently blogged about on the Web (you can find them in the benchmark directory of the libxml distribution). From http://depixelate.com/2008/4/23/ruby-xml-parsing-benchmarks user system total real libxml 0.032000 0.000000 0.032000 ( 0.031000) Hpricot 0.640000 0.031000 0.671000 ( 0.890000) REXML 1.813000 0.047000 1.860000 ( 2.031000) From https://svn.concord.org/svn/projects/trunk/common/ruby/xml_benchmarks/ user system total real libxml 0.641000 0.031000 0.672000 ( 0.672000) hpricot 5.359000 0.062000 5.421000 ( 5.516000) rexml 22.859000 0.047000 22.906000 ( 23.203000) == Documentation Documentation is available via rdoc, and is installed automatically with the gem. libxml-ruby's {online documentation}[https://xml4r.github.io/libxml-ruby/rdoc/index.html] is generated using Hanna, which is a development gem dependency. Note that older versions of Rdoc, which ship with Ruby 1.8.x, will report a number of errors. To avoid them, install Rdoc 2.1 or higher. Once you have installed the gem, you'll have to disable the version of Rdoc that Ruby 1.8.x includes. An easy way to do that is rename the directory ruby/lib/ruby/1.8/rdoc to ruby/lib/ruby/1.8/rdoc_old. == Support If you have any questions about using libxml-ruby, please report an issue on GitHub[https://github.com/xml4r/libxml-ruby/issues]. == Memory Management libxml-ruby automatically manages memory associated with the underlying libxml2 library. The bindings create a one-to-one mapping between Ruby objects and libxml documents and libxml parent nodes (ie, nodes that do not have a parent and do not belong to a document). In these cases, the bindings manage the memory. They do this by installing a free function and storing a back pointer to the Ruby object from the xmlnode using the _private member on libxml structures. When the Ruby object goes out of scope, the underlying libxml structure is freed. Libxml itself then frees all child nodes (recursively). For all other nodes (the vast majority), the bindings create temporary Ruby objects that get freed once they go out of scope. Thus there can be more than one Ruby object pointing to the same xml node. To mostly hide this from a programmer on the Ruby side, the #eql? and #== methods are overriden to check if two Ruby objects wrap the same xmlnode. If they do, then the methods return true. During the mark phase, each of these temporary objects marks its owning document, thereby keeping the Ruby document object alive and thus the xmldoc tree. In the sweep phase of the garbage collector, or when a program ends, there is no order to how Ruby objects are freed. In fact, the Ruby document object is almost always freed before any Ruby objects that wrap child nodes. However, this is ok because those Ruby objects do not have a free function and are no longer in scope (since if they were the document would not be freed). == License See LICENSE for license information. libxml-ruby-3.2.1/setup.rb0000644000004100000410000011151613760147770015521 0ustar www-datawww-data# # setup.rb # # Copyright (c) 2000-2005 Minero Aoki # # This program is free software. # You can distribute/modify this program under the terms of # the GNU LGPL, Lesser General Public License version 2.1. # unless Enumerable.method_defined?(:map) # Ruby 1.4.6 module Enumerable alias map collect end end unless File.respond_to?(:read) # Ruby 1.6 def File.read(fname) open(fname) {|f| return f.read } end end unless Errno.const_defined?(:ENOTEMPTY) # Windows? module Errno class ENOTEMPTY # We do not raise this exception, implementation is not needed. end end end def File.binread(fname) open(fname, 'rb') {|f| return f.read } end # for corrupted Windows' stat(2) def File.dir?(path) File.directory?((path[-1,1] == '/') ? path : path + '/') end class ConfigTable include Enumerable def initialize(rbconfig) @rbconfig = rbconfig @items = [] @table = {} # options @install_prefix = nil @config_opt = nil @verbose = true @no_harm = false end attr_accessor :install_prefix attr_accessor :config_opt attr_writer :verbose def verbose? @verbose end attr_writer :no_harm def no_harm? @no_harm end def [](key) lookup(key).resolve(self) end def []=(key, val) lookup(key).set val end def names @items.map {|i| i.name } end def each(&block) @items.each(&block) end def key?(name) @table.key?(name) end def lookup(name) @table[name] or setup_rb_error "no such config item: #{name}" end def add(item) @items.push item @table[item.name] = item end def remove(name) item = lookup(name) @items.delete_if {|i| i.name == name } @table.delete_if {|name, i| i.name == name } item end def load_script(path, inst = nil) if File.file?(path) MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path end end def savefile '.config' end def load_savefile begin File.foreach(savefile()) do |line| k, v = *line.split(/=/, 2) self[k] = v.strip end rescue Errno::ENOENT setup_rb_error $!.message + "\n#{File.basename($0)} config first" end end def save @items.each {|i| i.value } File.open(savefile(), 'w') {|f| @items.each do |i| f.printf "%s=%s\n", i.name, i.value if i.value? and i.value end } end def load_standard_entries standard_entries(@rbconfig).each do |ent| add ent end end def standard_entries(rbconfig) c = rbconfig rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT']) major = c['MAJOR'].to_i minor = c['MINOR'].to_i teeny = c['TEENY'].to_i version = "#{major}.#{minor}" # ruby ver. >= 1.4.4? newpath_p = ((major >= 2) or ((major == 1) and ((minor >= 5) or ((minor == 4) and (teeny >= 4))))) if c['rubylibdir'] # V > 1.6.3 libruby = "#{c['prefix']}/lib/ruby" librubyver = c['rubylibdir'] librubyverarch = c['archdir'] siteruby = c['sitedir'] siterubyver = c['sitelibdir'] siterubyverarch = c['sitearchdir'] elsif newpath_p # 1.4.4 <= V <= 1.6.3 libruby = "#{c['prefix']}/lib/ruby" librubyver = "#{c['prefix']}/lib/ruby/#{version}" librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}" siteruby = c['sitedir'] siterubyver = "$siteruby/#{version}" siterubyverarch = "$siterubyver/#{c['arch']}" else # V < 1.4.4 libruby = "#{c['prefix']}/lib/ruby" librubyver = "#{c['prefix']}/lib/ruby/#{version}" librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}" siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby" siterubyver = siteruby siterubyverarch = "$siterubyver/#{c['arch']}" end parameterize = lambda {|path| path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix') } if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg } makeprog = arg.sub(/'/, '').split(/=/, 2)[1] else makeprog = 'make' end [ ExecItem.new('installdirs', 'std/site/home', 'std: install under libruby; site: install under site_ruby; home: install under $HOME')\ {|val, table| case val when 'std' table['rbdir'] = '$librubyver' table['sodir'] = '$librubyverarch' when 'site' table['rbdir'] = '$siterubyver' table['sodir'] = '$siterubyverarch' when 'home' setup_rb_error '$HOME was not set' unless ENV['HOME'] table['prefix'] = ENV['HOME'] table['rbdir'] = '$libdir/ruby' table['sodir'] = '$libdir/ruby' end }, PathItem.new('prefix', 'path', c['prefix'], 'path prefix of target environment'), PathItem.new('bindir', 'path', parameterize.call(c['bindir']), 'the directory for commands'), PathItem.new('libdir', 'path', parameterize.call(c['libdir']), 'the directory for libraries'), PathItem.new('datadir', 'path', parameterize.call(c['datadir']), 'the directory for shared data'), PathItem.new('mandir', 'path', parameterize.call(c['mandir']), 'the directory for man pages'), PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']), 'the directory for system configuration files'), PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']), 'the directory for local state data'), PathItem.new('libruby', 'path', libruby, 'the directory for ruby libraries'), PathItem.new('librubyver', 'path', librubyver, 'the directory for standard ruby libraries'), PathItem.new('librubyverarch', 'path', librubyverarch, 'the directory for standard ruby extensions'), PathItem.new('siteruby', 'path', siteruby, 'the directory for version-independent aux ruby libraries'), PathItem.new('siterubyver', 'path', siterubyver, 'the directory for aux ruby libraries'), PathItem.new('siterubyverarch', 'path', siterubyverarch, 'the directory for aux ruby binaries'), PathItem.new('rbdir', 'path', '$siterubyver', 'the directory for ruby scripts'), PathItem.new('sodir', 'path', '$siterubyverarch', 'the directory for ruby extentions'), PathItem.new('rubypath', 'path', rubypath, 'the path to set to #! line'), ProgramItem.new('rubyprog', 'name', rubypath, 'the ruby program using for installation'), ProgramItem.new('makeprog', 'name', makeprog, 'the make program to compile ruby extentions'), SelectItem.new('shebang', 'all/ruby/never', 'ruby', 'shebang line (#!) editing mode'), BoolItem.new('without-ext', 'yes/no', 'no', 'does not compile/install ruby extentions') ] end private :standard_entries def load_multipackage_entries multipackage_entries().each do |ent| add ent end end def multipackage_entries [ PackageSelectionItem.new('with', 'name,name...', '', 'ALL', 'package names that you want to install'), PackageSelectionItem.new('without', 'name,name...', '', 'NONE', 'package names that you do not want to install') ] end private :multipackage_entries ALIASES = { 'std-ruby' => 'librubyver', 'stdruby' => 'librubyver', 'rubylibdir' => 'librubyver', 'archdir' => 'librubyverarch', 'site-ruby-common' => 'siteruby', # For backward compatibility 'site-ruby' => 'siterubyver', # For backward compatibility 'bin-dir' => 'bindir', 'rb-dir' => 'rbdir', 'so-dir' => 'sodir', 'data-dir' => 'datadir', 'ruby-path' => 'rubypath', 'ruby-prog' => 'rubyprog', 'ruby' => 'rubyprog', 'make-prog' => 'makeprog', 'make' => 'makeprog' } def fixup ALIASES.each do |ali, name| @table[ali] = @table[name] end @items.freeze @table.freeze @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/ end def parse_opt(opt) m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}" m.to_a[1,2] end def dllext @rbconfig['DLEXT'] end def value_config?(name) lookup(name).value? end class Item def initialize(name, template, default, desc) @name = name.freeze @template = template @value = default @default = default @description = desc end attr_reader :name attr_reader :description attr_accessor :default alias help_default default def help_opt "--#{@name}=#{@template}" end def value? true end def value @value end def resolve(table) @value.gsub(%r<\$([^/]+)>) { table[$1] } end def set(val) @value = check(val) end private def check(val) setup_rb_error "config: --#{name} requires argument" unless val val end end class BoolItem < Item def config_type 'bool' end def help_opt "--#{@name}" end private def check(val) return 'yes' unless val case val when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes' when /\An(o)?\z/i, /\Af(alse)\z/i then 'no' else setup_rb_error "config: --#{@name} accepts only yes/no for argument" end end end class PathItem < Item def config_type 'path' end private def check(path) setup_rb_error "config: --#{@name} requires argument" unless path path[0,1] == '$' ? path : File.expand_path(path) end end class ProgramItem < Item def config_type 'program' end end class SelectItem < Item def initialize(name, selection, default, desc) super @ok = selection.split('/') end def config_type 'select' end private def check(val) unless @ok.include?(val.strip) setup_rb_error "config: use --#{@name}=#{@template} (#{val})" end val.strip end end class ExecItem < Item def initialize(name, selection, desc, &block) super name, selection, nil, desc @ok = selection.split('/') @action = block end def config_type 'exec' end def value? false end def resolve(table) setup_rb_error "$#{name()} wrongly used as option value" end undef set def evaluate(val, table) v = val.strip.downcase unless @ok.include?(v) setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})" end @action.call v, table end end class PackageSelectionItem < Item def initialize(name, template, default, help_default, desc) super name, template, default, desc @help_default = help_default end attr_reader :help_default def config_type 'package' end private def check(val) unless File.dir?("packages/#{val}") setup_rb_error "config: no such package: #{val}" end val end end class MetaConfigEnvironment def initialize(config, installer) @config = config @installer = installer end def config_names @config.names end def config?(name) @config.key?(name) end def bool_config?(name) @config.lookup(name).config_type == 'bool' end def path_config?(name) @config.lookup(name).config_type == 'path' end def value_config?(name) @config.lookup(name).config_type != 'exec' end def add_config(item) @config.add item end def add_bool_config(name, default, desc) @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc) end def add_path_config(name, default, desc) @config.add PathItem.new(name, 'path', default, desc) end def set_config_default(name, default) @config.lookup(name).default = default end def remove_config(name) @config.remove(name) end # For only multipackage def packages raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer @installer.packages end # For only multipackage def declare_packages(list) raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer @installer.packages = list end end end # class ConfigTable # This module requires: #verbose?, #no_harm? module FileOperations def mkdir_p(dirname, prefix = nil) dirname = prefix + File.expand_path(dirname) if prefix $stderr.puts "mkdir -p #{dirname}" if verbose? return if no_harm? # Does not check '/', it's too abnormal. dirs = File.expand_path(dirname).split(%r<(?=/)>) if /\A[a-z]:\z/i =~ dirs[0] disk = dirs.shift dirs[0] = disk + dirs[0] end dirs.each_index do |idx| path = dirs[0..idx].join('') Dir.mkdir path unless File.dir?(path) end end def rm_f(path) $stderr.puts "rm -f #{path}" if verbose? return if no_harm? force_remove_file path end def rm_rf(path) $stderr.puts "rm -rf #{path}" if verbose? return if no_harm? remove_tree path end def remove_tree(path) if File.symlink?(path) remove_file path elsif File.dir?(path) remove_tree0 path else force_remove_file path end end def remove_tree0(path) Dir.foreach(path) do |ent| next if ent == '.' next if ent == '..' entpath = "#{path}/#{ent}" if File.symlink?(entpath) remove_file entpath elsif File.dir?(entpath) remove_tree0 entpath else force_remove_file entpath end end begin Dir.rmdir path rescue Errno::ENOTEMPTY # directory may not be empty end end def move_file(src, dest) force_remove_file dest begin File.rename src, dest rescue File.open(dest, 'wb') {|f| f.write File.binread(src) } File.chmod File.stat(src).mode, dest File.unlink src end end def force_remove_file(path) begin remove_file path rescue end end def remove_file(path) File.chmod 0777, path File.unlink path end def install(from, dest, mode, prefix = nil) $stderr.puts "install #{from} #{dest}" if verbose? return if no_harm? realdest = prefix ? prefix + File.expand_path(dest) : dest realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest) str = File.binread(from) if diff?(str, realdest) verbose_off { rm_f realdest if File.exist?(realdest) } File.open(realdest, 'wb') {|f| f.write str } File.chmod mode, realdest File.open("#{objdir_root()}/InstalledFiles", 'a') {|f| if prefix f.puts realdest.sub(prefix, '') else f.puts realdest end } end end def diff?(new_content, path) return true unless File.exist?(path) new_content != File.binread(path) end def command(*args) $stderr.puts args.join(' ') if verbose? system(*args) or raise RuntimeError, "system(#{args.map{|a| a.inspect }.join(' ')}) failed" end def ruby(*args) command config('rubyprog'), *args end def make(task = nil) command(*[config('makeprog'), task].compact) end def extdir?(dir) File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb") end def files_of(dir) Dir.open(dir) {|d| return d.select {|ent| File.file?("#{dir}/#{ent}") } } end DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn ) def directories_of(dir) Dir.open(dir) {|d| return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT } end end # This module requires: #srcdir_root, #objdir_root, #relpath module HookScriptAPI def get_config(key) @config[key] end alias config get_config # obsolete: use metaconfig to change configuration def set_config(key, val) @config[key] = val end # # srcdir/objdir (works only in the package directory) # def curr_srcdir "#{srcdir_root()}/#{relpath()}" end def curr_objdir "#{objdir_root()}/#{relpath()}" end def srcfile(path) "#{curr_srcdir()}/#{path}" end def srcexist?(path) File.exist?(srcfile(path)) end def srcdirectory?(path) File.dir?(srcfile(path)) end def srcfile?(path) File.file?(srcfile(path)) end def srcentries(path = '.') Dir.open("#{curr_srcdir()}/#{path}") {|d| return d.to_a - %w(. ..) } end def srcfiles(path = '.') srcentries(path).select {|fname| File.file?(File.join(curr_srcdir(), path, fname)) } end def srcdirectories(path = '.') srcentries(path).select {|fname| File.dir?(File.join(curr_srcdir(), path, fname)) } end end class ToplevelInstaller Version = '3.4.1' Copyright = 'Copyright (c) 2000-2005 Minero Aoki' TASKS = [ [ 'all', 'do config, setup, then install' ], [ 'config', 'saves your configurations' ], [ 'show', 'shows current configuration' ], [ 'setup', 'compiles ruby extentions and others' ], [ 'install', 'installs files' ], [ 'test', 'run all tests in test/' ], [ 'clean', "does `make clean' for each extention" ], [ 'distclean',"does `make distclean' for each extention" ] ] def ToplevelInstaller.invoke config = ConfigTable.new(load_rbconfig()) config.load_standard_entries config.load_multipackage_entries if multipackage? config.fixup klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller) klass.new(File.dirname($0), config).invoke end def ToplevelInstaller.multipackage? File.dir?(File.dirname($0) + '/packages') end def ToplevelInstaller.load_rbconfig if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg } ARGV.delete(arg) load File.expand_path(arg.split(/=/, 2)[1]) $".push 'rbconfig.rb' else require 'rbconfig' end ::Config::CONFIG end def initialize(ardir_root, config) @ardir = File.expand_path(ardir_root) @config = config # cache @valid_task_re = nil end def config(key) @config[key] end def inspect "#<#{self.class} #{__id__()}>" end def invoke run_metaconfigs case task = parsearg_global() when nil, 'all' parsearg_config init_installers exec_config exec_setup exec_install else case task when 'config', 'test' ; when 'clean', 'distclean' @config.load_savefile if File.exist?(@config.savefile) else @config.load_savefile end __send__ "parsearg_#{task}" init_installers __send__ "exec_#{task}" end end def run_metaconfigs @config.load_script "#{@ardir}/metaconfig" end def init_installers @installer = Installer.new(@config, @ardir, File.expand_path('.')) end # # Hook Script API bases # def srcdir_root @ardir end def objdir_root '.' end def relpath '.' end # # Option Parsing # def parsearg_global while arg = ARGV.shift case arg when /\A\w+\z/ setup_rb_error "invalid task: #{arg}" unless valid_task?(arg) return arg when '-q', '--quiet' @config.verbose = false when '--verbose' @config.verbose = true when '--help' print_usage $stdout exit 0 when '--version' puts "#{File.basename($0)} version #{Version}" exit 0 when '--copyright' puts Copyright exit 0 else setup_rb_error "unknown global option '#{arg}'" end end nil end def valid_task?(t) valid_task_re() =~ t end def valid_task_re @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/ end def parsearg_no_options unless ARGV.empty? task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1) setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}" end end alias parsearg_show parsearg_no_options alias parsearg_setup parsearg_no_options alias parsearg_test parsearg_no_options alias parsearg_clean parsearg_no_options alias parsearg_distclean parsearg_no_options def parsearg_config evalopt = [] set = [] @config.config_opt = [] while i = ARGV.shift if /\A--?\z/ =~ i @config.config_opt = ARGV.dup break end name, value = *@config.parse_opt(i) if @config.value_config?(name) @config[name] = value else evalopt.push [name, value] end set.push name end evalopt.each do |name, value| @config.lookup(name).evaluate value, @config end # Check if configuration is valid set.each do |n| @config[n] if @config.value_config?(n) end end def parsearg_install @config.no_harm = false @config.install_prefix = '' while a = ARGV.shift case a when '--no-harm' @config.no_harm = true when /\A--prefix=/ path = a.split(/=/, 2)[1] path = File.expand_path(path) unless path[0,1] == '/' @config.install_prefix = path else setup_rb_error "install: unknown option #{a}" end end end def print_usage(out) out.puts 'Typical Installation Procedure:' out.puts " $ ruby #{File.basename $0} config" out.puts " $ ruby #{File.basename $0} setup" out.puts " # ruby #{File.basename $0} install (may require root privilege)" out.puts out.puts 'Detailed Usage:' out.puts " ruby #{File.basename $0} " out.puts " ruby #{File.basename $0} [] []" fmt = " %-24s %s\n" out.puts out.puts 'Global options:' out.printf fmt, '-q,--quiet', 'suppress message outputs' out.printf fmt, ' --verbose', 'output messages verbosely' out.printf fmt, ' --help', 'print this message' out.printf fmt, ' --version', 'print version and quit' out.printf fmt, ' --copyright', 'print copyright and quit' out.puts out.puts 'Tasks:' TASKS.each do |name, desc| out.printf fmt, name, desc end fmt = " %-24s %s [%s]\n" out.puts out.puts 'Options for CONFIG or ALL:' @config.each do |item| out.printf fmt, item.help_opt, item.description, item.help_default end out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's" out.puts out.puts 'Options for INSTALL:' out.printf fmt, '--no-harm', 'only display what to do if given', 'off' out.printf fmt, '--prefix=path', 'install path prefix', '' out.puts end # # Task Handlers # def exec_config @installer.exec_config @config.save # must be final end def exec_setup @installer.exec_setup end def exec_install @installer.exec_install end def exec_test @installer.exec_test end def exec_show @config.each do |i| printf "%-20s %s\n", i.name, i.value if i.value? end end def exec_clean @installer.exec_clean end def exec_distclean @installer.exec_distclean end end # class ToplevelInstaller class ToplevelInstallerMulti < ToplevelInstaller include FileOperations def initialize(ardir_root, config) super @packages = directories_of("#{@ardir}/packages") raise 'no package exists' if @packages.empty? @root_installer = Installer.new(@config, @ardir, File.expand_path('.')) end def run_metaconfigs @config.load_script "#{@ardir}/metaconfig", self @packages.each do |name| @config.load_script "#{@ardir}/packages/#{name}/metaconfig" end end attr_reader :packages def packages=(list) raise 'package list is empty' if list.empty? list.each do |name| raise "directory packages/#{name} does not exist"\ unless File.dir?("#{@ardir}/packages/#{name}") end @packages = list end def init_installers @installers = {} @packages.each do |pack| @installers[pack] = Installer.new(@config, "#{@ardir}/packages/#{pack}", "packages/#{pack}") end with = extract_selection(config('with')) without = extract_selection(config('without')) @selected = @installers.keys.select {|name| (with.empty? or with.include?(name)) \ and not without.include?(name) } end def extract_selection(list) a = list.split(/,/) a.each do |name| setup_rb_error "no such package: #{name}" unless @installers.key?(name) end a end def print_usage(f) super f.puts 'Inluded packages:' f.puts ' ' + @packages.sort.join(' ') f.puts end # # Task Handlers # def exec_config run_hook 'pre-config' each_selected_installers {|inst| inst.exec_config } run_hook 'post-config' @config.save # must be final end def exec_setup run_hook 'pre-setup' each_selected_installers {|inst| inst.exec_setup } run_hook 'post-setup' end def exec_install run_hook 'pre-install' each_selected_installers {|inst| inst.exec_install } run_hook 'post-install' end def exec_test run_hook 'pre-test' each_selected_installers {|inst| inst.exec_test } run_hook 'post-test' end def exec_clean rm_f @config.savefile run_hook 'pre-clean' each_selected_installers {|inst| inst.exec_clean } run_hook 'post-clean' end def exec_distclean rm_f @config.savefile run_hook 'pre-distclean' each_selected_installers {|inst| inst.exec_distclean } run_hook 'post-distclean' end # # lib # def each_selected_installers Dir.mkdir 'packages' unless File.dir?('packages') @selected.each do |pack| $stderr.puts "Processing the package `#{pack}' ..." if verbose? Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}") Dir.chdir "packages/#{pack}" yield @installers[pack] Dir.chdir '../..' end end def run_hook(id) @root_installer.run_hook id end # module FileOperations requires this def verbose? @config.verbose? end # module FileOperations requires this def no_harm? @config.no_harm? end end # class ToplevelInstallerMulti class Installer FILETYPES = %w( bin lib ext data conf man ) include FileOperations include HookScriptAPI def initialize(config, srcroot, objroot) @config = config @srcdir = File.expand_path(srcroot) @objdir = File.expand_path(objroot) @currdir = '.' end def inspect "#<#{self.class} #{File.basename(@srcdir)}>" end def noop(rel) end # # Hook Script API base methods # def srcdir_root @srcdir end def objdir_root @objdir end def relpath @currdir end # # Config Access # # module FileOperations requires this def verbose? @config.verbose? end # module FileOperations requires this def no_harm? @config.no_harm? end def verbose_off begin save, @config.verbose = @config.verbose?, false yield ensure @config.verbose = save end end # # TASK config # def exec_config exec_task_traverse 'config' end alias config_dir_bin noop alias config_dir_lib noop def config_dir_ext(rel) extconf if extdir?(curr_srcdir()) end alias config_dir_data noop alias config_dir_conf noop alias config_dir_man noop def extconf ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt end # # TASK setup # def exec_setup exec_task_traverse 'setup' end def setup_dir_bin(rel) files_of(curr_srcdir()).each do |fname| update_shebang_line "#{curr_srcdir()}/#{fname}" end end alias setup_dir_lib noop def setup_dir_ext(rel) make if extdir?(curr_srcdir()) end alias setup_dir_data noop alias setup_dir_conf noop alias setup_dir_man noop def update_shebang_line(path) return if no_harm? return if config('shebang') == 'never' old = Shebang.load(path) if old $stderr.puts "warning: #{path}: Shebang line includes too many args. It is not portable and your program may not work." if old.args.size > 1 new = new_shebang(old) return if new.to_s == old.to_s else return unless config('shebang') == 'all' new = Shebang.new(config('rubypath')) end $stderr.puts "updating shebang: #{File.basename(path)}" if verbose? open_atomic_writer(path) {|output| File.open(path, 'rb') {|f| f.gets if old # discard output.puts new.to_s output.print f.read } } end def new_shebang(old) if /\Aruby/ =~ File.basename(old.cmd) Shebang.new(config('rubypath'), old.args) elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby' Shebang.new(config('rubypath'), old.args[1..-1]) else return old unless config('shebang') == 'all' Shebang.new(config('rubypath')) end end def open_atomic_writer(path, &block) tmpfile = File.basename(path) + '.tmp' begin File.open(tmpfile, 'wb', &block) File.rename tmpfile, File.basename(path) ensure File.unlink tmpfile if File.exist?(tmpfile) end end class Shebang def Shebang.load(path) line = nil File.open(path) {|f| line = f.gets } return nil unless /\A#!/ =~ line parse(line) end def Shebang.parse(line) cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ') new(cmd, args) end def initialize(cmd, args = []) @cmd = cmd @args = args end attr_reader :cmd attr_reader :args def to_s "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}") end end # # TASK install # def exec_install rm_f 'InstalledFiles' exec_task_traverse 'install' end def install_dir_bin(rel) install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755 end def install_dir_lib(rel) install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644 end def install_dir_ext(rel) return unless extdir?(curr_srcdir()) install_files rubyextentions('.'), "#{config('sodir')}/#{File.dirname(rel)}", 0555 end def install_dir_data(rel) install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644 end def install_dir_conf(rel) # FIXME: should not remove current config files # (rename previous file to .old/.org) install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644 end def install_dir_man(rel) install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644 end def install_files(list, dest, mode) mkdir_p dest, @config.install_prefix list.each do |fname| install fname, dest, mode, @config.install_prefix end end def libfiles glob_reject(%w(*.y *.output), targetfiles()) end def rubyextentions(dir) ents = glob_select("*.#{@config.dllext}", targetfiles()) if ents.empty? setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first" end ents end def targetfiles mapdir(existfiles() - hookfiles()) end def mapdir(ents) ents.map {|ent| if File.exist?(ent) then ent # objdir else "#{curr_srcdir()}/#{ent}" # srcdir end } end # picked up many entries from cvs-1.11.1/src/ignore.c JUNK_FILES = %w( core RCSLOG tags TAGS .make.state .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb *~ *.old *.bak *.BAK *.orig *.rej _$* *$ *.org *.in .* ) def existfiles glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.'))) end def hookfiles %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt| %w( config setup install clean ).map {|t| sprintf(fmt, t) } }.flatten end def glob_select(pat, ents) re = globs2re([pat]) ents.select {|ent| re =~ ent } end def glob_reject(pats, ents) re = globs2re(pats) ents.reject {|ent| re =~ ent } end GLOB2REGEX = { '.' => '\.', '$' => '\$', '#' => '\#', '*' => '.*' } def globs2re(pats) /\A(?:#{ pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|') })\z/ end # # TASK test # TESTDIR = 'test' def exec_test unless File.directory?('test') $stderr.puts 'no test in this package' if verbose? return end $stderr.puts 'Running tests...' if verbose? begin require 'test/unit' rescue LoadError setup_rb_error 'test/unit cannot loaded. You need Ruby 1.8 or later to invoke this task.' end runner = Test::Unit::AutoRunner.new(true) runner.to_run << TESTDIR runner.run end # # TASK clean # def exec_clean exec_task_traverse 'clean' rm_f @config.savefile rm_f 'InstalledFiles' end alias clean_dir_bin noop alias clean_dir_lib noop alias clean_dir_data noop alias clean_dir_conf noop alias clean_dir_man noop def clean_dir_ext(rel) return unless extdir?(curr_srcdir()) make 'clean' if File.file?('Makefile') end # # TASK distclean # def exec_distclean exec_task_traverse 'distclean' rm_f @config.savefile rm_f 'InstalledFiles' end alias distclean_dir_bin noop alias distclean_dir_lib noop def distclean_dir_ext(rel) return unless extdir?(curr_srcdir()) make 'distclean' if File.file?('Makefile') end alias distclean_dir_data noop alias distclean_dir_conf noop alias distclean_dir_man noop # # Traversing # def exec_task_traverse(task) run_hook "pre-#{task}" FILETYPES.each do |type| if type == 'ext' and config('without-ext') == 'yes' $stderr.puts 'skipping ext/* by user option' if verbose? next end traverse task, type, "#{task}_dir_#{type}" end run_hook "post-#{task}" end def traverse(task, rel, mid) dive_into(rel) { run_hook "pre-#{task}" __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '') directories_of(curr_srcdir()).each do |d| traverse task, "#{rel}/#{d}", mid end run_hook "post-#{task}" } end def dive_into(rel) return unless File.dir?("#{@srcdir}/#{rel}") dir = File.basename(rel) Dir.mkdir dir unless File.dir?(dir) prevdir = Dir.pwd Dir.chdir dir $stderr.puts '---> ' + rel if verbose? @currdir = rel yield Dir.chdir prevdir $stderr.puts '<--- ' + rel if verbose? @currdir = File.dirname(rel) end def run_hook(id) path = [ "#{curr_srcdir()}/#{id}", "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) } return unless path begin instance_eval File.read(path), path, 1 rescue raise if $DEBUG setup_rb_error "hook #{path} failed:\n" + $!.message end end end # class Installer class SetupError < StandardError; end def setup_rb_error(msg) raise SetupError, msg end if $0 == __FILE__ begin ToplevelInstaller.invoke rescue SetupError raise if $DEBUG $stderr.puts $!.message $stderr.puts "Try 'ruby #{$0} --help' for detailed usage." exit 1 end end libxml-ruby-3.2.1/HISTORY0000644000004100000410000007506213760147770015125 0ustar www-datawww-data= Release History == 3.2.1 / 2020-11-05 * Fix incorrect handling of encodings when using XMLWriter.io (Charlie Savage) * Clean up README (Richard Michael) == 3.2.0 / 2020-05-09 Charlie Savage * Fix crash when creating an empty DTD * Modernize tests to use Bundler to load gem * Add libxml-ruby.rb file so gem loads in expected way. * Add support for xmlSaveNoEmptyTags. * Clean up extconf.rb file == 3.1.0 / 2018-02-03 Charlie Savage * Fix segmentation fault when adding one node to another node (Charlie Savage) * Fix deprecated "assert_equal(nil, expected)" calls. #148 and #151. (utilum) * Remove assigned but unused variables. #150 (utilum) * Add Gemfile. #146. (Dorian Marié) * Remove duplicate hash key in setup.rb. #147. (Dorian Marié) * Fix gemspec by requiring Date. #149 (utilum) * Restore default internal encoding after tests are completed. #123 (Charlie Savage) * Remove duplicate method definitions. #145. (Charlie Savage) * Remove SchemaElement#minOccurs and SchemaElement#maxOccurs since they actually did not work (Charlie Savage) * Rename test files to follow Ruby conventions (Charlie Savage) * Fix handling of node returned by Reader#expand. #142. (Charlie Savage) * Add Travis Build support (Charlie Savage) * Fix Fixnum deprecation (Charlie Savage) * Cleanup schema code (Charlie Savage) * Update Visual Studio project to 2017 (Charlie Savage) == 3.0.0 / 2017-02-07 Charlie Savage * Revamp how libxml-ruby manages memory. Instead of trying to return the same ruby object for each xmlnode, the bindings now create wrapper ruby objects as needed which are then freed at the end of use. This allows most memory management to be handled by libxml itself. Ruby only manages the lifespan of documents and parent xml nodes. When those go out of scope, the underlying libxml objects are also freed. This implementation requires almost no overhead, plays nicely with Nokogiri and appears to work much better (Charlie Savage). * Change XML::Node#eql? API. Nodes are now considered equal only if they wrap the same underlying libxml node. Previously, they would also be considered equal if they contained the same content (Charlie Savage) * Change XML::Reader.expand API. Previously it would automatically instantiate a reader document so the an xpath expression could be used to search the returned node. Now you should first call reader.doc (Charlie Savage) * Update Visual Studio project for Visual Studio 15 - requires ruby 2.4+ (Charlie Savage) * Remove APIs that have been deprecated for several years (Charlie Savage) == 2.9.0 / 2016-06-13 Charlie Savage * Revamp libxml-ruby's memory management to not cause crashes when used with Nokogiri (James Laird-Wah) * Fix garbage collection issue that sometimes caused the library to hang (Charlie Savage) * Improved multi-threading support (Charlie Savage) * Fix crash sometimes caused by a xml node being being freed twice (Charlie Savage) * Fix memory leak when setting the text content of a node (Charlie Savage) * Set a default task in the Rakefile - use "test" (Robert Haines) * Add "hanna_gudao" gem and add "rake-compiler" to develpoment dependencies (Robert Haines) * Use Process.getrlimit instead of `ulimit` in the tests (Robert Haines) * Build on smartos (Steven Williamson) * Fix compiler warnings (Charlie Savage) * Add Xcode project for easier debugging on OSX (Charlie Savage) * Switch from unit test to minitest (Charlie Savage) == 2.8.0 / 2015-01-09 Charlie Savage * Use RbConfig instead of Config in extconf.rb (Robert Haines) * Correct xpath documentation XML (Bill Mill) * Correct from_string method documentation (Bill Mill) * Fix compile error with debug not enabled in libxml (Patrick Ziegler) * Update gemspec to include license (Charlie Savage) * In XML::Writer prevent writing to io while being GCed (Brett Gibson) == 2.7.0 / 2013-08-13 Charlie Savage * Don't call rb_warning in GC mark function (Dirkjan Bussink) * Set libxml error handler when a libxml-ruby error handler is set (Geoffrey Giesemann) * Fix tests for nil TypeErrors for ruby 2.0=< (Geoffrey Giesemann) * Fix segmentation fault for issue #62 (Charlie Savage) * Add #node_type method to dtd (Charlie Savage) * Fixing equality check of LibXML::XML::Error against other objects (Michał Szajbe) * Fix #63, XML::Writer.set_quote_char UT, wrong expected string (julp) * Fix potential segfault when GC occurs while creating ns from xpath (Timothy Elliott) * Fix for #59, segmentation fault after failure to load external schema (Clifford Heath) == 2.6.0 / 2013-02-16 Charlie Savage * Fix uninitialized constant LibXML::XML::Error::I18N (NameError) that occurred with older versions of libxml. * Various updates/fixes to new XML::Writer class and update how flushing works (julp) == 2.5.0 / 2013-01-27 Charlie Savage * Compatibility with older versions for IO::write (rb_io_bufwrite is specific to ruby >= 1.9.3?) and symbols are VALUE not ID (julp). * Fix version for xmlTextWriterSetQuoteChar, it appeared in libxml2 2.9.0, last version (julp) * Update use of LIBXML_VERSION (julp). * Fix misuse of rb_scan_args (julp). * Update documentation, including DTD docs and added XML Writer (julp). * Added a new XML::Writer class (julp). * Improved xml reader api and add namespace support. Note that passing a numeric value to XML::Reader::move_to_attribute has been deprecated. Instead you should now use #move_to_attribute_no. (julp). * Improve error handling and messages (Jarl Friis) == 2.4.0 / 2012-12-14 Charlie Savage * Support libxml 2.9.0 (Daniel Veillard) * Extensive new interfaces for xml schema functionality including suppor for schemal elements, types, facets and attributes (Anton Sozontov) * Fix Encoding#from_s bug and update docs (Nikita Afanasenko) * Node#content= encoding (Nikita Afanasenko) == 2.3.3 / 2012-07-01 Charlie Savage * Add LibXML::XML::Error.get_handler (Carsten Zimmermann) * Fix variable name in example (Marcus) == 2.3.2 / 2012-03-20 Charlie Savage * Define various canonicalize constants to support libxml2 versions older than 1.1.25 (thanks Apple!) == 2.3.1 / 2012-03-20 Charlie Savage * Yanked - didn't fix the OSX canonicalize issue == 2.3.0 / 2012-03-18 Charlie Savage * Add ability to insert new PI-nodes into the xmltree (Axel Struebing). * Added full pass-through access to libxml2 xmlC14NDocDumpMemory method via LibXML::XML::Document#canonicalize method with optional arguments. * Added full test data for C14N based off of W3C spec. (http://www.w3.org/TR/xml-c14n#Examples) * Update sax handler to support encodings on Ruby 1.9 and higher. == 2.2.2 / 2011-08-29 Charlie Savage * ++API CHANGE+++ Reader#relax_ng_validate now takes a RelaxNG object. This is what the documentation has always said it takes, but it previously took a string. In addition, it now returns true or false instead of 0 or -1. Reader#schema_validate now takes a Schema object. This is what the documentation has always said it takes, but it previously took a string. In addition, it now returns true or false instead of 0 or -1. Fixes GitHub issue #30. * Added Parser::Context#close and HTMLParser::Context#close methods that allow the underlying io stream (file, string, etc) to be closed. Once a parser is done parsing its data, it now calls one of these methods. This means that if you parse thousands of files at the same time, without running Ruby's garbage colllector, you won't get a too many files open error. Fixes GitHub issue #29. * Fixed bug where Node#inner_xml caused an error when it had no child nodes. Fixes GitHub issues #31 * Don't require 'rake' in the gemspec to avoid annoying Bundler bugs == 2.2.1 / 2011-08-13 Charlie Savage * Packaging fix - include the custom .def file in the gem. == 2.2.0 / 2011-08-09 Charlie Savage * Update encoding support for Ruby 1.9 so that libxml-ruby returns strings encoded in UTF-8. This change was required since libxml internally stores strings in UTF-8. The exceptions to this rule are the #to_s methods which return UTF-8 by default but can return other encodings if requested. == 2.1.2 / 2011-08-03 Charlie Savage * Fix segmentation fault that could occur when an XPathContext was marked before it was fully initialized (Charlie Savage). * Add mark method to document to mark all nodes currently being accessed by ruby. This make Ruby Enterprise Edition happy (Charlie Savage). == 2.1.1 / 2011-07-31 Charlie Savage * Switch to using def files to control library exports (Charlie Savage). == 2.1.0 / 2011-07-31 Charlie Savage * Ruby 1.9.3 compatability (Charlie Savage). * Added XPath expression <-> Ruby value conversion methods (Jens Wille). * Extracted rxml_xpath_to_value from rxml_xpath_context_find (Jens Wille). * Adapted rxml_xpath_from_value from Gregoire Lejeune's ruby-xslt library, see https://github.com/glejeune/ruby-xslt (Jens Wille). * Allow calling #find on nodes returned from Reader (Charlie Savage). * Change document handling in XPath::Context to address segmentation fault on Ruby Enterprise Edition (Charlie Savage). * Update gemspec file to work directly with bundler thereby allowing git repository to be used as gem (Charlie Savage). * Support gem buld (Charlie Savage). * Simplify memory management of attributes namespaces to fix segmentation faults that occurred when using Ruby 1.9.3 (Charlie Savage). == 2.0.8 / 2011-06-23 Charlie Savage * Add in 2 new HTML Parser constants - NODEFDTD and NOIMPLIED. * Fix compile issue on Ruby 1.9.3 == 2.0.6 / 2011-05-23 Charlie Savage * Fix segfault that sometimes occurred when looking up encodings on 1.9. In some cases the Ruby encoding infrastructure was not properly initialized (nkriege). == 2.0.5 / 2011-05-05 Charlie Savage * Document#validate_dtd would sometimes cause segmentation faults due to an improperly initialized data structure (Charlie Savage) == 2.0.4 / 2011-05-02 Charlie Savage * Fix compile issues on platforms using older versions of libxml2. The problem as using a C14N constants that was added to libxml2 in July 2009 (Charlie Savage). == 2.0.3 / 2011-05-01 Charlie Savage * The biggest change in this release is supporting the use of libxml-ruby in native background Ruby threads. Previously, the use of libxml-ruby in background threads in Ruby 1.9.x and higher would often cause segmentation faults. This has now been fixed (Charlie Savage). * Update Reader#expand so that returned node correctly remembers its encoding in Ruby 1.9.x (zerebubuth). * Add check to verify a node has not been deleted. This can happen when a ruby variable holds a reference to a child node that gets freed when its parent gets freed. Previously when this happened a segmentation fault would occur, now an exception is raised (Charlie Savage, fixes RubyForge #26839. * Do not unlink nodes before internal validations have run - avoids segmentation faults caused by freeing a node twice (Charlie Savage). * Add support for Document#canonicalization (Victor Lin). * Fix memory leak in Reader#lookup_namespace (Charlie Savage). * Fix memory leak in Reader#[] (Nathan Kriege). * Fix usage of @io instance variable (Jeffrey Taylor) * Removed old sax error handling code that has been fixed in newer versions of libxml (Charlie Savage). * Code cleanup - remove unused variables and commented out code (Charlie Savage) * Minor text changes and documentation fixes (Charlie Savage). * Fix documentation error (fixes RubyForge #26888). * Update documentation for Document#validation* methods (fixes RubyForge #24833). * Update documentation and test (fixes Ruby Forge Issue #28770). * Updated documentation in README (Anurag Priyam): 1. rake doc does not work; use rake rdoc. 2. gem mislav-hanna does not exist; use hanna. 3. rake rdoc 'depends' on hanna; no need of RDOCOPTS 4. Point to the github issue tracker instead of Ruby Forge 5. Point to the github (gh-pages) site for docs * Add tc_error to test suite (Charlie Savage). * Add sax test (Stanislav O.Pogrebnyak). == 2.0.2 / 2011-04-17 Charlie Savage * Added binaries for windows (Charlie Savage). * Update Ruby 1.9 encoding handling to support libxml versions older than version 2.6.26 which was released on June 6, 2006 (Charlie Savage). * Add publish_with_docs rake task - combines publishing the website and docs (Anurag Priyam). * Correctly copy the documentation directory (Anurag Priyam) * Use relative link for rdoc so the links are correct on both rubyforge and github (Anurag Priyam). * Update Rakefile to use Hanna RDco template (Charlie Savage). * Update dates on license file (Charlie Savage). * Add api to allow setting of attribute namespaces. Fixes issue #10 (Charlie Savage). * Remove old hack to call the on_error method. This hack isn't needed anymore since a better workaround was put in place in the parser context. Fixes This fixes issue #12 (Charlie Savage). * Remove references to passing blocks to validation functions. The blocks are no longer called since the bindings use libxml's structured error handling. See issue #6 (Charlie Savage). * Fix up comment in Document and Node. See issue #8 (Charlie Savage). * Update website text (Charlie Savage). == 2.0.0 / 2011-04-16 Charlie Savage * Ruby 1.9.2 support. The biggest addition is encoding support. Strings returned by the libxml bindings are now set to the encoding of the underlying xml document (Charlie Savage). * Rubinius compatability. Removed unnecessary use of RHASH_TBL (Aman Gupta) * Added .gemspec file (Dudley Flanders). * Updated Windows checks to take into account mingw32 (Yaohan Chen). * Fix memory leak in Reader#Expand (Szymon Nowak). * Fix memory leaks in Reader#read_string, Reader#read_inner_xml and Reader#read_outer_xml (Sean Geoghegan). * Node#space_preserve= was backwards (Dudley Flanders) * Fixed typo in readme, added rdoc extension (Loren Sands-Ramshaw). * Switched to Rake Compiler (Charlie Savage). * Use xmlMalloc() memory for ctxt->sax structure. Sometimes the ctxt->sax pointer may not be zeroed in rxml_sax_parser_parse(), for example when exception is raised in one of callbacks. This lets xmlFreeParserCtxt() clean this up (Alexey I. Froloff). * Added a rake task to publish the website to github. Moved the jekyll website to web directory (Anurag Priyam). * Modernize project metadata and layout (7rans) == 1.1.3 / 2009-03-18 Charlie Savage * Improve performance 10 to 20% by turning on libxml2's dictionary feature that allows parsers to reuse previously parsed strings. * Fix XML::Node#remove! to work correctly with libxml's dictionary feature. * Correctly set up parser context options. * Simplify DOM modification code (Node#next=, Node#prev=, Node#sibling=) and update documentation. * Deprecated Node#add_child and Node#child=, use Node#<< instead * Fix documentation for Node#<< * Added Document#import to enable moving nodes from one document to another document. == 1.1.2 / 2009-03-12 Charlie Savage * Added XML::Node#inner_xml helper method. * Fix segmentation that could occur when calling the mark function on a previously freed node. == 1.1.1 / 2009-03-10 Charlie Savage * Fix - Only include extra html parser context methods for versions of libxml older than 2.6.27. == 1.1.0 / 2009-03-09 Charlie Savage * Fix bug caused by the mark function being called on partially initialized attributes. * Revert back to libxml2's internal memory manager. == 1.0.0 / 2009-03-05 Charlie Savage * OS X (Charlie Savage). Update bindings to support the default installed version of libxml2 (2.6.16) on OS X 10.5 and the latest version available via MacPorts. == 0.9.9 / 2009-03-05 Charlie Savage * Ruby 1.9.1 support (Charlie Savage). libxml-ruby now compiles and runs on either 1.8.6 and 1.9.1. With 1.8.6 all tests should pass while on 1.9.1 all but for encoding tests pass. The port to Ruby 1.9.1 revealed two memory allocation bugs (one with dtds, one with nodes) which are now fixed. * Better OS X support (Joe Khoobyar). The default version of libxml2 on OS X 10.5 is fairly old, resulting in this link error: NSLinkModule() error dyld: Symbol not found: _htmlNewParserCtxt This can be fixed by using MacPorts to get a newer version of libxml2. To make use of MacPorts, the build script has been updated to use xml2-config. This can be fine-tuned using the new --with-xml2-config / --without-xml2-config options to extconf.rb (default is --without-xml2-config to match existing behavior). * Greatly reduced memory usage (Joe Khoobyar). See http://rubyforge.org/pipermail/libxml-devel/2009-February/001375.html. * Add Document#xhtml? and document#node_type methods (Joe Khoobyar) * Add XPath::Object#last (Joe Khoobyar) * Provide finer control over CDATA nodes on a parser by parser basis (Joe Khoobyar). * Bug fix - Namespaces were incorrectly merged with attributes in the new sax2 handler (Charlie Savage). * Bug fix - Support iterating over nodes and attributes even with blocks that call remove! (Charlie Savage) * Bug fix - If reader.node is NULL, return nil instead of crashing (Charlie Savage) * Bug fix - Dtd's owned by documents were freed twice in some circumstances (Joe Khoobyar). * Bug fix - Fix output escaping on attributes nodes (Joe Khoobyar). * Bug fix - Make sure IO objects are not garbage collected when used as parser sources (Charlie Savage). == 0.9.8 / 2009-1-24 Charlie Savage * Refactored XML::Parser, XML::HTMLParser, XML::SaxParser and XML::Reader to have consistent APIs. All the parsers now take a context object in their constructors, allowing fine grained control over the parsers for advanced use cases. These API changes are backwards compatible except for XML::Reader, which now takes an optional hash table as a second parameter in its various constructors versus an optional boolean value. * Updated all APIs to use the encoding constants defined in XML::Encoding versus string values. This API change is not backwards compatible. * Added support for attribute declarations in DTD's via the new XML::AttrDecl class (Len Lattanzi) * Support libxml's content escaping capabilities for text nodes by wrapping libxml's "xmlStringText" and "xmlStringTextNoenc" (Joe Khoobyar). * Updated XML::Reader#read API to return true if a node was read, false if node was not read and raises an exception on an error. Previously #read returned 1 if a node was read, 0 if a node was not read and -1 for an error. This change is not backwards compatible, but provides a more natural interface for Ruby by allowing code like this: while reader.read # do stuff end * Changed XML::Error exception objects to return copies of nodes that cause parse errors instead of the original node. This prevents segmentation faults when the error is reraised. * Added XML::Reader#node method. * Fixed compile errors on OS X which uses an older version of libxml. * Fixed memory leak when performing XPath searches. * Fixed rdocs. * Don't override libxml's default settings for entity substitution and loading external DTDs. This may break some code - you may need to add in a call to XML.default_substitute_entities = true or XML.default_load_external_dtd = true. == 0.9.7 / 2008-12-08 Charlie Savage * Added SAX2 support. SAX handlers now define two new callbacks, on_start_element_ns and on_end_element_ns methods. These new callbacks support namespaces, making them superior to the older callbacks on_start_element and on_end_element methods. The old callbacks are still supported, but may be deprecated in the future depending on community feedback. * Added SAX support for libxml's structured error handling. That menas sax handlers now define a new callback, on_error, which takes one parameter, an instance of XML::Error. The older on_parser_error, on_parser_warning and on_parser_fatal_error callbacks are no longer suported so you must port your code. Note that the older callbacks took one string parameter, instead of an XML::Error object. * Experimental work-around for libxml error handling bug - see http://mail.gnome.org/archives/xml/2008-December/msg00014.html for more information. * Fix compilation bugs on Solaris. * Fix Rdoc compilation bug. == 0.9.6 / 2008-12-08 Charlie Savage * Refactored namespace handling. The existing, and inconsistent, namespace methods defined on XML::Node have been deprecated. They have been replaced by a the new XML::Namespaces class. Use this class to inspect a node's namespace, its default namespace, its namespace definitions and which namespaces are in scope. It can be accessed via the the XML::Node#namespaces method. * Rationalized XML::Document#save, XML::Document#to_s and XML::Node#to_s to take an optional hash table of parameters that control how output is generated. Supported parameters include setting indentation on or off, the indentation level and the output encoding. This is an API change and may break existing calls to XML::Document#save. However, the previous API was broken - setting the encoding resulted in an error so its unlikely anyone is using it. * Rationalized XML::Document#debug, XML::Node#debug, XML::XPath::XPathObject#Debug. * Deprecated a number of duplicate dump* and debug_* methods in XML::Document and XML::Node. * Additional Ruby 1.9.1 compatability fixes. * Cleaned up header file guards. == 0.9.5 / 2008-11-29 Charlie Savage * Ruby 1.9.1 preview release compatability (Felipe Contreras) * Update Node#remove! to return the removed node and to set its document to nil. This allows the node to be either moved to another document, another part of the same document or to be freed on the next garbage collection once its references have gone out of scope. * Fix bug where XPathExpression#compile mistakenly overwrote RegExp#compile. * Update Node to use standard ruby allocators and initializers. * Update HTML parser to be more forgiving of invalid documents. * Update include paths for Darwin Ports on OS X. * Updated C code base to use BSD/Allman style == 0.9.4 / 2008-11-24 Charlie Savage * Update HTML parser so that it can read files, strings and io streams. * Update HTML parser to support user specified encodings. * Additional C code cleanup. == 0.9.3 / 2008-11-22 Charlie Savage * Fixed segmentation fault caused by documents being freed before xpath results that referenced the document (take 2). * Allowed sax parser to use io stream * Combined encoding and input classes * Cleaned up C code - removed remaining legacy structures, added static to most methods, changed C namespace from ruby_xml to rxml == 0.9.2 / 2008-11-19 Charlie Savage * Add support for compiled XPath expressions (donated by Pavel Valodzka) * Fixes for compiling on OS X 10.5.4 and 10.5.5 == 0.9.1 / 2008-11-18 Charlie Savage * Expose LibXML's encoding support via a new Encoding object. * Revamp error handling to be much easier to use. Errors are now wrapped by the new XML::Error class and are thrown as exceptions when it is appropriate. * Fixed segmentation fault caused by documents being freed before xpath results that referenced the document. * Add Node#register_default_namespace to simplify default namespace handling. * Significantly improve documentation * A number of bug fixes and patches. == 0.9.0 / 2008-11-18 Charlie Savage * Version 0.9.0 was removed due to packaging errors. == 0.8.3 / 2008-07-21 Charlie Savage * Missed several files in last release == 0.8.2 / 2008-07-21 Charlie Savage * To use LibXML you can either require 'xml' or require 'libxml'. The differences is that require 'xml' mixes the LibXML module into the global namespace, thereby allowing you to write code such as document = XML::Document.new. Note that this is different from 0.8.0 and 0.8.1 and may require updating your code. * Support RelaxNG validation (thanks to Morus Walter) * Support passing IO objects to XmlReaders (thanks to Tom Hughes) * Fix segmentation fault caused by adding an attribute to a CDATA node * Moved node checking functions from C to Ruby * Improved Windows support - libxml-ruby should now work out of the box. * Improved Windows support - turned on libxml's zlib and iconv support. == 0.8.1 / 2008-07-09 Charlie Savage * Reimplmented Node#each_attr for backwards compatability * Moved node type test to Ruby. == 0.8.0 / 2008-07-09 Charlie Savage * Fixed bug in returning attributes from XPath results * Fixed DOM traversal methods * Changed Node#children to return an array of nodes * Fixed bug in returning attributes from XPath results * Refactored XPath support, providing more user hooks in the XPath::Context class * Added Node#properties for backwards compatibility * Updated setup.rb * Added more tests * Updated rdocs and README file * Moved libxml into LibXML namespace == 0.7.0 / 2008-07-09 Charlie Savage * Added new attributes class to provide a more natural way of working with attributes * Fixed XML::Attr to better support namespaces * Added documentation on how to use namespaces with XPath * Removed allocation of extraneous structures used to wrap nodes, namespaces and attributes * Cleaned up tests and added new test suite * Updated rdocs and README file * Cleaned out most of the bug list == 0.6.0 / 2008-07-01 Charlie Savage * Fixed memory allocation errors in Windows. On Windows, it is essential that the same library that allocates memory must free it. Thus ALLOC calls must be matched to ruby_xfree calls, which they were not. In addition, in one case Ruby was allocating memory to be freed by libxml. On Windows, that's a segmentation fault. On Linux it might fly, but still seems like a bad idea. * Fixed segmentation fault in xml reader expand (same xml tree freed twice) * Applied a number of patches from Tom Bagby, including fixes for xpath segmentation faults and fixes for various memory leaks * Cleaned up a number of compiler warnings * Renamed libxml_so.so to libxml_ruby.so (same for xslt). That wasn't actually my original intention, but um, it kind of sort of happened. It should not be noticeable from an end-user perspective. * Added rake files for building with MingW * Added rake files for packing gems. Note that I did this outside the existing rake tasks because I didn't see how they were actually building the gems. * Cleaned up the tests and added a few more based on bug reports from the Tracker and mailing list. * Cleaned out the patch queue and went through about 1/2 the bug list === 2007-11-16 "Dan Janowski" * Merged Dan's MEM2 branch to trunk. == 0.5.3 / === 2007-11-16 "Dan Janowski" * Merged Dan's MEM2 branch to trunk. == 0.5.2 / 2007-10-10 === 2007-10-10 "Dan Janowski" * (Dan, fill in the major points of the changes you made up to here -thanks) === 2007-01-14 "Laurent Sansonetti" * Added some preliminary RDoc comments for XML::Reader. === 2006-12-05 "Laurent Sansonetti" * Added XML::Reader, a set of bindings to the xmlTextReader API. == 0.3.8.4 / 2006-12-02 === 2006-04-15 "Ross Bamform" * Implemented SAX parser callback handling. === 2006-04-12 "Ross Bamford" * Integrated and tested community patches. * Defined XML::Node (hash) equality in terms of XML representation. === 2006-04-12 "Tim Yamin" * Fixed XML::Node#content inoperable bug (plasmaroo) [patch] * Fixed memory leak in same === 2006-04-12 "Mark Van Holstyn" * Added XML::Node::Set#first (mvette13) [patch] * Added XML::Node::Set#empty? * Fixed XML::Node::Set#to_a * Added XML::Node#find_first * Added XML::Node#remove! === 2006-03-27 "Ross Bamford" * Integrated contributed XML::Parser.register_error_handler patch (rosco) === 2006-02-27 "Ross Bamford" * Fixed all multiple symbol definitions for -fno-common. * Removed OSX -fno-common workaround. == 0.3.6 / 2006-02-23 === 2006-02-21 "Ross Bamford" * Patched extconf.rb with OSX -fno-common workaround * Added gem and packaging support to Rakefile * Moved version update to Rakefile * Removed legacy project utility scripts === 2005-02-19 "Ross Bamford" * Fixed doublefree bug in ruby_xml_attr. * Fixed small leak in parser === 2005-12-18 "Ross Bamford" * Updated for GCC 4.0 (community patches) * Fixed default validation bug * Refactored project, removed outdated files, cleaned up tests. * Added RDoc documentation across .c files. * Fixed up a few strings. === 2004-04-04 "Mangler Jurgen" * ruby_xml_node.cz: fixed ruby_xml_node_property_set. The ill-behaviour was, that there was added a second attribute of the same name, when you were setting the value of an already existing attribute. === 2004-03-17 "Lukas Svoboda" * ruby_xml_node.c: ruby_xml_node_to_s now returns XML subtree dump. === 2004-02-27 "Martin Povolny" * ruby_xml_node.c: added XML::Node.copy, this makes possible building of xml documents from nodes taken from other xml documents without making ruby SIGSEGV (see tests/copy_bug.rb). === 2004-02-26 "Martin Povolny" * ruby_xml_dtd.c, ruby_xml_dtd.h, ruby_xml_schema.c, ruby_xml_schema.h: more work on validation, now you can actually validate document using dtd or xml schema, also solved warning and error propagation (see tests/{dtd|schema}-test.rb). === 2003-12-30 "Martin Povolny" * ruby_xml_dtd.c, ruby_xml_dtd.h, ruby_xml_schema.c, ruby_xml_schema.h: prelimitary support for dtd and schema validation === 2003-09-15 "Martin Povolny" * ruby_xml_input_cbg.c, libxml.c: added class InputCallbacks to make possible registering custom input callbacks handlers (xmlRegisterInputCallbacks) written in ruby === 2003-08-01 "Martin Povolny" * ruby_xml_document.c: corrected argument handling in ruby_xml_document_find * ruby_xml_node.c: corrected argument handling in ruby_xml_node_find libxml-ruby-3.2.1/ext/0000755000004100000410000000000013760147770014627 5ustar www-datawww-datalibxml-ruby-3.2.1/ext/vc/0000755000004100000410000000000013760147770015237 5ustar www-datawww-datalibxml-ruby-3.2.1/ext/vc/libxml_ruby.sln0000644000004100000410000000243713760147770020313 0ustar www-datawww-data Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxml_ruby", "libxml_ruby\libxml_ruby.vcxproj", "{0B65CD1D-EEB9-41AE-93BB-75496E504152}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0B65CD1D-EEB9-41AE-93BB-75496E504152}.Debug|x64.ActiveCfg = Debug|x64 {0B65CD1D-EEB9-41AE-93BB-75496E504152}.Debug|x64.Build.0 = Debug|x64 {0B65CD1D-EEB9-41AE-93BB-75496E504152}.Debug|x86.ActiveCfg = Debug|x64 {0B65CD1D-EEB9-41AE-93BB-75496E504152}.Debug|x86.Build.0 = Debug|x64 {0B65CD1D-EEB9-41AE-93BB-75496E504152}.Release|x64.ActiveCfg = Release|x64 {0B65CD1D-EEB9-41AE-93BB-75496E504152}.Release|x64.Build.0 = Release|x64 {0B65CD1D-EEB9-41AE-93BB-75496E504152}.Release|x86.ActiveCfg = Release|Win32 {0B65CD1D-EEB9-41AE-93BB-75496E504152}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal libxml-ruby-3.2.1/ext/libxml/0000755000004100000410000000000013760147770016116 5ustar www-datawww-datalibxml-ruby-3.2.1/ext/libxml/ruby_xml_parser_options.c0000644000004100000410000000570113760147770023255 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include #include "ruby_libxml.h" /* Document-class: LibXML::XML::Parser::Options * * Options that control the operation of the HTMLParser. The easiest * way to set a parser's options is to use the methods * XML::Parser.file, XML::Parser.io or XML::Parser.string. * For additional control, see XML::Parser::Context#options=. */ VALUE mXMLParserOptions; void rxml_init_parser_options(void) { mXMLParserOptions = rb_define_module_under(cXMLParser, "Options"); /* recover on errors */ rb_define_const(mXMLParserOptions, "RECOVER", INT2NUM(XML_PARSE_RECOVER)); /* substitute entities */ rb_define_const(mXMLParserOptions, "NOENT", INT2NUM(XML_PARSE_NOENT)); /* load the external subset */ rb_define_const(mXMLParserOptions, "DTDLOAD", INT2NUM(XML_PARSE_DTDLOAD)); /* default DTD attributes */ rb_define_const(mXMLParserOptions, "DTDATTR", INT2NUM(XML_PARSE_DTDATTR)); /* validate with the DTD */ rb_define_const(mXMLParserOptions, "DTDVALID", INT2NUM(XML_PARSE_DTDVALID)); /* suppress error reports */ rb_define_const(mXMLParserOptions, "NOERROR", INT2NUM(XML_PARSE_NOERROR)); /* suppress warning reports */ rb_define_const(mXMLParserOptions, "NOWARNING", INT2NUM(XML_PARSE_NOWARNING)); /* pedantic error reporting */ rb_define_const(mXMLParserOptions, "PEDANTIC", INT2NUM(XML_PARSE_PEDANTIC)); /* remove blank nodes */ rb_define_const(mXMLParserOptions, "NOBLANKS", INT2NUM(XML_PARSE_NOBLANKS)); /* use the SAX1 interface internally */ rb_define_const(mXMLParserOptions, "SAX1", INT2NUM(XML_PARSE_SAX1)); /* Implement XInclude substitition */ rb_define_const(mXMLParserOptions, "XINCLUDE", INT2NUM(XML_PARSE_XINCLUDE)); /* Forbid network access */ rb_define_const(mXMLParserOptions, "NONET", INT2NUM(XML_PARSE_NONET)); /* Do not reuse the context dictionnary */ rb_define_const(mXMLParserOptions, "NODICT", INT2NUM(XML_PARSE_NODICT)); /* remove redundant namespaces declarations */ rb_define_const(mXMLParserOptions, "NSCLEAN", INT2NUM(XML_PARSE_NSCLEAN)); /* merge CDATA as text nodes */ rb_define_const(mXMLParserOptions, "NOCDATA", INT2NUM(XML_PARSE_NOCDATA)); #if LIBXML_VERSION >= 20621 /* do not generate XINCLUDE START/END nodes */ rb_define_const(mXMLParserOptions, "NOXINCNODE", INT2NUM(XML_PARSE_NOXINCNODE)); #endif #if LIBXML_VERSION >= 20700 /* compact small text nodes */ rb_define_const(mXMLParserOptions, "COMPACT", INT2NUM(XML_PARSE_COMPACT)); /* parse using XML-1.0 before update 5 */ rb_define_const(mXMLParserOptions, "PARSE_OLD10", INT2NUM(XML_PARSE_OLD10)); /* do not fixup XINCLUDE xml:base uris */ rb_define_const(mXMLParserOptions, "NOBASEFIX", INT2NUM(XML_PARSE_NOBASEFIX)); #endif #if LIBXML_VERSION >= 20703 /* relax any hardcoded limit from the parser */ rb_define_const(mXMLParserOptions, "HUGE", INT2NUM(XML_PARSE_HUGE)); #endif } libxml-ruby-3.2.1/ext/libxml/ruby_xml_writer.h0000644000004100000410000000027313760147770021526 0ustar www-datawww-data#ifndef __RXML_WRITER__ #define __RXML_WRITER__ #ifdef LIBXML_WRITER_ENABLED #include #endif extern VALUE cXMLWriter; void rxml_init_writer(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_schema.c0000644000004100000410000001602713760147770021451 0ustar www-datawww-data#include "ruby_libxml.h" #define LIBXML_OUTPUT_ENABLED #define DUMP_CONTENT_MODEL #include "ruby_xml_schema.h" #include "ruby_xml_schema_type.h" #include "ruby_xml_schema_element.h" #include "ruby_xml_schema_attribute.h" #include "ruby_xml_schema_facet.h" /* * Document-class: LibXML::XML::Schema * * The XML::Schema class is used to prepare XML Schemas for validation of xml * documents. * * Schemas can be created from XML documents, strinings or URIs using the * corresponding methods (new for URIs). * * Once a schema is prepared, an XML document can be validated by the * XML::Document#validate_schema method providing the XML::Schema object * as parameter. The method return true if the document validates, false * otherwise. * * Basic usage: * * # parse schema as xml document * schema_document = XML::Document.file('schema.rng') * * # prepare schema for validation * schema = XML::Schema.document(schema_document) * * # parse xml document to be validated * instance = XML::Document.file('instance.xml') * * # validate * instance.validate_schema(schema) */ VALUE cXMLSchema; static void rxml_schema_free(xmlSchemaPtr xschema) { xmlSchemaFree(xschema); } VALUE rxml_wrap_schema(xmlSchemaPtr xschema) { return Data_Wrap_Struct(cXMLSchema, NULL, rxml_schema_free, xschema); } /* * call-seq: * XML::Schema.initialize(schema_uri) -> schema * * Create a new schema from the specified URI. */ static VALUE rxml_schema_init_from_uri(VALUE class, VALUE uri) { xmlSchemaParserCtxtPtr xparser; xmlSchemaPtr xschema; Check_Type(uri, T_STRING); xparser = xmlSchemaNewParserCtxt(StringValuePtr(uri)); xschema = xmlSchemaParse(xparser); xmlSchemaFreeParserCtxt(xparser); return Data_Wrap_Struct(cXMLSchema, NULL, rxml_schema_free, xschema); } /* * call-seq: * XML::Schema.document(document) -> schema * * Create a new schema from the specified document. */ static VALUE rxml_schema_init_from_document(VALUE class, VALUE document) { xmlDocPtr xdoc; xmlSchemaPtr xschema; xmlSchemaParserCtxtPtr xparser; Data_Get_Struct(document, xmlDoc, xdoc); xparser = xmlSchemaNewDocParserCtxt(xdoc); xschema = xmlSchemaParse(xparser); xmlSchemaFreeParserCtxt(xparser); if (xschema == NULL) return Qnil; return Data_Wrap_Struct(cXMLSchema, NULL, rxml_schema_free, xschema); } /* * call-seq: * XML::Schema.from_string("schema_data") -> "value" * * Create a new schema using the specified string. */ static VALUE rxml_schema_init_from_string(VALUE self, VALUE schema_str) { xmlSchemaParserCtxtPtr xparser; xmlSchemaPtr xschema; Check_Type(schema_str, T_STRING); xparser = xmlSchemaNewMemParserCtxt(StringValuePtr(schema_str), (int)strlen(StringValuePtr(schema_str))); xschema = xmlSchemaParse(xparser); xmlSchemaFreeParserCtxt(xparser); return Data_Wrap_Struct(cXMLSchema, NULL, rxml_schema_free, xschema); } static VALUE rxml_schema_target_namespace(VALUE self) { xmlSchemaPtr xschema; Data_Get_Struct(self, xmlSchema, xschema); QNIL_OR_STRING(xschema->targetNamespace) } static VALUE rxml_schema_name(VALUE self) { xmlSchemaPtr xschema; Data_Get_Struct(self, xmlSchema, xschema); QNIL_OR_STRING(xschema->name) } static VALUE rxml_schema_version(VALUE self) { xmlSchemaPtr xschema; Data_Get_Struct(self, xmlSchema, xschema); QNIL_OR_STRING(xschema->version) } static VALUE rxml_schema_id(VALUE self) { xmlSchemaPtr xschema; Data_Get_Struct(self, xmlSchema, xschema); QNIL_OR_STRING(xschema->id) } static VALUE rxml_schema_document(VALUE self) { xmlSchemaPtr xschema; Data_Get_Struct(self, xmlSchema, xschema); return rxml_node_wrap(xmlDocGetRootElement(xschema->doc)); } static void scan_namespaces(xmlSchemaImportPtr ximport, VALUE array, xmlChar *nsname) { xmlNodePtr xnode; xmlNsPtr xns; if (ximport->doc) { xnode = xmlDocGetRootElement(ximport->doc); xns = xnode->nsDef; while (xns) { VALUE namespace = rxml_namespace_wrap(xns); rb_ary_push(array, namespace); xns = xns->next; } } } static VALUE rxml_schema_namespaces(VALUE self) { VALUE result; xmlSchemaPtr xschema; Data_Get_Struct(self, xmlSchema, xschema); result = rb_ary_new(); xmlHashScan(xschema->schemasImports, (xmlHashScanner)scan_namespaces, (void *)result); return result; } static void scan_element(xmlSchemaElementPtr xelement, VALUE hash, xmlChar *name) { VALUE element = rxml_wrap_schema_element(xelement); rb_hash_aset(hash, rb_str_new2((const char*)name), element); } static VALUE rxml_schema_elements(VALUE self) { VALUE result = rb_hash_new(); xmlSchemaPtr xschema; Data_Get_Struct(self, xmlSchema, xschema); xmlHashScan(xschema->elemDecl, (xmlHashScanner)scan_element, (void *)result); return result; } static void scan_type(xmlSchemaTypePtr xtype, VALUE hash, xmlChar *name) { VALUE type = rxml_wrap_schema_type(xtype); rb_hash_aset(hash, rb_str_new2((const char*)name), type); } static VALUE rxml_schema_types(VALUE self) { VALUE result = rb_hash_new(); xmlSchemaPtr xschema; Data_Get_Struct(self, xmlSchema, xschema); if (xschema != NULL && xschema->typeDecl != NULL) { xmlHashScan(xschema->typeDecl, (xmlHashScanner)scan_type, (void *)result); } return result; } static void collect_imported_types(xmlSchemaImportPtr import, VALUE result) { if (import->imported && import->schema) { xmlHashScan(import->schema->typeDecl, (xmlHashScanner)scan_type, (void *)result); } } static VALUE rxml_schema_imported_types(VALUE self) { xmlSchemaPtr xschema; VALUE result = rb_hash_new(); Data_Get_Struct(self, xmlSchema, xschema); if (xschema) { xmlHashScan(xschema->schemasImports, (xmlHashScanner)collect_imported_types, (void *)result); } return result; } void rxml_init_schema(void) { cXMLSchema = rb_define_class_under(mXML, "Schema", rb_cObject); rb_define_singleton_method(cXMLSchema, "new", rxml_schema_init_from_uri, 1); rb_define_singleton_method(cXMLSchema, "from_string", rxml_schema_init_from_string, 1); rb_define_singleton_method(cXMLSchema, "document", rxml_schema_init_from_document, 1); rb_define_method(cXMLSchema, "target_namespace", rxml_schema_target_namespace, 0); rb_define_method(cXMLSchema, "name", rxml_schema_name, 0); rb_define_method(cXMLSchema, "id", rxml_schema_id, 0); rb_define_method(cXMLSchema, "version", rxml_schema_version, 0); rb_define_method(cXMLSchema, "document", rxml_schema_document, 0); rb_define_method(cXMLSchema, "elements", rxml_schema_elements, 0); rb_define_method(cXMLSchema, "imported_types", rxml_schema_imported_types, 0); rb_define_method(cXMLSchema, "namespaces", rxml_schema_namespaces, 0); rb_define_method(cXMLSchema, "types", rxml_schema_types, 0); rxml_init_schema_facet(); rxml_init_schema_element(); rxml_init_schema_attribute(); rxml_init_schema_type(); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_parser_context.h0000644000004100000410000000034713760147770023254 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_PARSER_CONTEXT__ #define __RXML_PARSER_CONTEXT__ extern VALUE cXMLParserContext; void rxml_init_parser_context(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_schema.h0000644000004100000410000005352613760147770021463 0ustar www-datawww-data#ifndef __RXML_SCHEMA__ #define __RXML_SCHEMA__ #include #include #include extern VALUE cXMLSchema; void rxml_init_schema(void); #define QNIL_OR_STRING(slot) \ if (slot == NULL) \ return Qnil; \ else \ return rb_str_new2((const char *)slot); #define SUBSET_RESTRICTION 1<<0 #define SUBSET_EXTENSION 1<<1 #define SUBSET_SUBSTITUTION 1<<2 #define SUBSET_LIST 1<<3 #define SUBSET_UNION 1<<4 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo; typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr; typedef struct _xmlSchemaItemList xmlSchemaItemList; typedef xmlSchemaItemList *xmlSchemaItemListPtr; struct _xmlSchemaItemList { void **items; /* used for dynamic addition of schemata */ int nbItems; /* used for dynamic addition of schemata */ int sizeItems; /* used for dynamic addition of schemata */ }; #define XML_SCHEMA_CTXT_PARSER 1 #define XML_SCHEMA_CTXT_VALIDATOR 2 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt; typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr; struct _xmlSchemaAbstractCtxt { int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */ }; typedef struct _xmlSchemaBucket xmlSchemaBucket; typedef xmlSchemaBucket *xmlSchemaBucketPtr; #define XML_SCHEMA_SCHEMA_MAIN 0 #define XML_SCHEMA_SCHEMA_IMPORT 1 #define XML_SCHEMA_SCHEMA_INCLUDE 2 #define XML_SCHEMA_SCHEMA_REDEFINE 3 /** * xmlSchemaSchemaRelation: * * Used to create a graph of schema relationships. */ typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation; typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr; struct _xmlSchemaSchemaRelation { xmlSchemaSchemaRelationPtr next; int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */ const xmlChar *importNamespace; xmlSchemaBucketPtr bucket; }; #define XML_SCHEMA_BUCKET_MARKED 1<<0 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1 struct _xmlSchemaBucket { int type; int flags; const xmlChar *schemaLocation; const xmlChar *origTargetNamespace; const xmlChar *targetNamespace; xmlDocPtr doc; xmlSchemaSchemaRelationPtr relations; int located; int parsed; int imported; int preserveDoc; xmlSchemaItemListPtr globals; /* Global components. */ xmlSchemaItemListPtr locals; /* Local components. */ }; /** * xmlSchemaImport: * (extends xmlSchemaBucket) * * Reflects a schema. Holds some information * about the schema and its toplevel components. Duplicate * toplevel components are not checked at this level. */ typedef struct _xmlSchemaImport xmlSchemaImport; typedef xmlSchemaImport *xmlSchemaImportPtr; struct _xmlSchemaImport { int type; /* Main OR import OR include. */ int flags; const xmlChar *schemaLocation; /* The URI of the schema document. */ /* For chameleon includes, @origTargetNamespace will be NULL */ const xmlChar *origTargetNamespace; /* * For chameleon includes, @targetNamespace will be the * targetNamespace of the including schema. */ const xmlChar *targetNamespace; xmlDocPtr doc; /* The schema node-tree. */ /* @relations will hold any included/imported/redefined schemas. */ xmlSchemaSchemaRelationPtr relations; int located; int parsed; int imported; int preserveDoc; xmlSchemaItemListPtr globals; xmlSchemaItemListPtr locals; /* The imported schema. */ xmlSchemaPtr schema; }; /* * (extends xmlSchemaBucket) */ typedef struct _xmlSchemaInclude xmlSchemaInclude; typedef xmlSchemaInclude *xmlSchemaIncludePtr; struct _xmlSchemaInclude { int type; int flags; const xmlChar *schemaLocation; const xmlChar *origTargetNamespace; const xmlChar *targetNamespace; xmlDocPtr doc; xmlSchemaSchemaRelationPtr relations; int located; int parsed; int imported; int preserveDoc; xmlSchemaItemListPtr globals; /* Global components. */ xmlSchemaItemListPtr locals; /* Local components. */ /* The owning main or import schema bucket. */ xmlSchemaImportPtr ownerImport; }; /** * xmlSchemaBasicItem: * * The abstract base type for schema components. */ typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem; typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr; struct _xmlSchemaBasicItem { xmlSchemaTypeType type; }; /** * xmlSchemaAnnotItem: * * The abstract base type for annotated schema components. * (Extends xmlSchemaBasicItem) */ typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem; typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr; struct _xmlSchemaAnnotItem { xmlSchemaTypeType type; xmlSchemaAnnotPtr annot; }; /** * xmlSchemaTreeItem: * * The abstract base type for tree-like structured schema components. * (Extends xmlSchemaAnnotItem) */ typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem; typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr; struct _xmlSchemaTreeItem { xmlSchemaTypeType type; xmlSchemaAnnotPtr annot; xmlSchemaTreeItemPtr next; xmlSchemaTreeItemPtr children; }; #define XML_SCHEMA_ATTR_USE_FIXED 1<<0 /** * xmlSchemaAttributeUsePtr: * * The abstract base type for tree-like structured schema components. * (Extends xmlSchemaTreeItem) */ typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse; typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr; struct _xmlSchemaAttributeUse { xmlSchemaTypeType type; xmlSchemaAnnotPtr annot; xmlSchemaAttributeUsePtr next; /* The next attr. use. */ /* * The attr. decl. OR a QName-ref. to an attr. decl. OR * a QName-ref. to an attribute group definition. */ xmlSchemaAttributePtr attrDecl; int flags; xmlNodePtr node; int occurs; /* required, optional */ const xmlChar *defValue; xmlSchemaValPtr defVal; }; /** * xmlSchemaAttributeUseProhibPtr: * * A helper component to reflect attribute prohibitions. * (Extends xmlSchemaBasicItem) */ typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib; typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr; struct _xmlSchemaAttributeUseProhib { xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */ xmlNodePtr node; const xmlChar *name; const xmlChar *targetNamespace; int isRef; }; /** * xmlSchemaRedef: */ typedef struct _xmlSchemaRedef xmlSchemaRedef; typedef xmlSchemaRedef *xmlSchemaRedefPtr; struct _xmlSchemaRedef { xmlSchemaRedefPtr next; xmlSchemaBasicItemPtr item; /* The redefining component. */ xmlSchemaBasicItemPtr reference; /* The referencing component. */ xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */ const xmlChar *refName; /* The name of the to-be-redefined component. */ const xmlChar *refTargetNs; /* The target namespace of the to-be-redefined comp. */ xmlSchemaBucketPtr targetBucket; /* The redefined schema. */ }; /** * xmlSchemaConstructionCtxt: */ typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt; typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr; struct _xmlSchemaConstructionCtxt { xmlSchemaPtr mainSchema; /* The main schema. */ xmlSchemaBucketPtr mainBucket; /* The main schema bucket */ xmlDictPtr dict; xmlSchemaItemListPtr buckets; /* List of schema buckets. */ /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */ xmlSchemaBucketPtr bucket; /* The current schema bucket */ xmlSchemaItemListPtr pending; /* All Components of all schemas that need to be fixed. */ xmlHashTablePtr substGroups; xmlSchemaRedefPtr redefs; xmlSchemaRedefPtr lastRedef; }; #define XML_SCHEMAS_PARSE_ERROR 1 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT struct _xmlSchemaParserCtxt { int type; void *errCtxt; /* user specific error context */ xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ int err; int nberrors; xmlStructuredErrorFunc serror; xmlSchemaConstructionCtxtPtr constructor; int ownsConstructor; /* TODO: Move this to parser *flags*. */ /* xmlSchemaPtr topschema; */ /* xmlHashTablePtr namespaces; */ xmlSchemaPtr schema; /* The main schema in use */ int counter; const xmlChar *URL; xmlDocPtr doc; int preserve; /* Whether the doc should be freed */ const char *buffer; int size; /* * Used to build complex element content models */ xmlAutomataPtr am; xmlAutomataStatePtr start; xmlAutomataStatePtr end; xmlAutomataStatePtr state; xmlDictPtr dict; /* dictionnary for interned string names */ xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */ int options; xmlSchemaValidCtxtPtr vctxt; int isS4S; int isRedefine; int xsiAssemble; int stop; /* If the parser should stop; i.e. a critical error. */ const xmlChar *targetNamespace; xmlSchemaBucketPtr redefined; /* The schema to be redefined. */ xmlSchemaRedefPtr redef; /* Used for redefinitions. */ int redefCounter; /* Used for redefinitions. */ xmlSchemaItemListPtr attrProhibs; }; /** * xmlSchemaQNameRef: * * A component reference item (not a schema component) * (Extends xmlSchemaBasicItem) */ typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef; typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr; struct _xmlSchemaQNameRef { xmlSchemaTypeType type; xmlSchemaBasicItemPtr item; /* The resolved referenced item. */ xmlSchemaTypeType itemType; const xmlChar *name; const xmlChar *targetNamespace; xmlNodePtr node; }; /** * xmlSchemaParticle: * * A particle component. * (Extends xmlSchemaTreeItem) */ typedef struct _xmlSchemaParticle xmlSchemaParticle; typedef xmlSchemaParticle *xmlSchemaParticlePtr; struct _xmlSchemaParticle { xmlSchemaTypeType type; xmlSchemaAnnotPtr annot; xmlSchemaTreeItemPtr next; /* next particle */ xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group, a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference), etc.) */ int minOccurs; int maxOccurs; xmlNodePtr node; }; /** * xmlSchemaModelGroup: * * A model group component. * (Extends xmlSchemaTreeItem) */ typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup; typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr; struct _xmlSchemaModelGroup { xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */ xmlSchemaAnnotPtr annot; xmlSchemaTreeItemPtr next; /* not used */ xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */ xmlNodePtr node; }; #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1 /** * xmlSchemaModelGroupDef: * * A model group definition component. * (Extends xmlSchemaTreeItem) */ typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef; typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr; struct _xmlSchemaModelGroupDef { xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */ xmlSchemaAnnotPtr annot; xmlSchemaTreeItemPtr next; /* not used */ xmlSchemaTreeItemPtr children; /* the "model group" */ const xmlChar *name; const xmlChar *targetNamespace; xmlNodePtr node; int flags; }; typedef struct _xmlSchemaIDC xmlSchemaIDC; typedef xmlSchemaIDC *xmlSchemaIDCPtr; /** * xmlSchemaIDCSelect: * * The identity-constraint "field" and "selector" item, holding the * XPath expression. */ typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect; typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr; struct _xmlSchemaIDCSelect { xmlSchemaIDCSelectPtr next; xmlSchemaIDCPtr idc; int index; /* an index position if significant for IDC key-sequences */ const xmlChar *xpath; /* the XPath expression */ void *xpathComp; /* the compiled XPath expression */ }; /** * xmlSchemaIDC: * * The identity-constraint definition component. * (Extends xmlSchemaAnnotItem) */ struct _xmlSchemaIDC { xmlSchemaTypeType type; xmlSchemaAnnotPtr annot; xmlSchemaIDCPtr next; xmlNodePtr node; const xmlChar *name; const xmlChar *targetNamespace; xmlSchemaIDCSelectPtr selector; xmlSchemaIDCSelectPtr fields; int nbFields; xmlSchemaQNameRefPtr ref; }; /** * xmlSchemaIDCAug: * * The augmented IDC information used for validation. */ typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug; typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr; struct _xmlSchemaIDCAug { xmlSchemaIDCAugPtr next; /* next in a list */ xmlSchemaIDCPtr def; /* the IDC definition */ int keyrefDepth; /* the lowest tree level to which IDC tables need to be bubbled upwards */ }; /** * xmlSchemaPSVIIDCKeySequence: * * The key sequence of a node table item. */ typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey; typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr; struct _xmlSchemaPSVIIDCKey { xmlSchemaTypePtr type; xmlSchemaValPtr val; }; /** * xmlSchemaPSVIIDCNode: * * The node table item of a node table. */ typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode; typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr; struct _xmlSchemaPSVIIDCNode { xmlNodePtr node; xmlSchemaPSVIIDCKeyPtr *keys; int nodeLine; int nodeQNameID; }; /** * xmlSchemaPSVIIDCBinding: * * The identity-constraint binding item of the [identity-constraint table]. */ typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding; typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr; struct _xmlSchemaPSVIIDCBinding { xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */ xmlSchemaIDCPtr definition; /* the IDC definition */ xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */ int nbNodes; /* number of entries in the node table */ int sizeNodes; /* size of the node table */ xmlSchemaItemListPtr dupls; }; #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2 #define XPATH_STATE_OBJ_MATCHES -2 #define XPATH_STATE_OBJ_BLOCKED -3 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher; typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr; /** * xmlSchemaIDCStateObj: * * The state object used to evaluate XPath expressions. */ typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj; typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr; struct _xmlSchemaIDCStateObj { int type; xmlSchemaIDCStateObjPtr next; /* next if in a list */ int depth; /* depth of creation */ int *history; /* list of (depth, state-id) tuples */ int nbHistory; int sizeHistory; xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector matcher */ xmlSchemaIDCSelectPtr sel; void *xpathCtxt; }; #define IDC_MATCHER 0 /** * xmlSchemaIDCMatcher: * * Used to evaluate IDC selectors (and fields). */ struct _xmlSchemaIDCMatcher { int type; int depth; /* the tree depth at creation time */ xmlSchemaIDCMatcherPtr next; /* next in the list */ xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */ xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */ int idcType; xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target elements */ int sizeKeySeqs; xmlSchemaItemListPtr targets; /* list of target-node (xmlSchemaPSVIIDCNodePtr) entries */ }; /* * Element info flags. */ #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1 #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4 #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10 /** * xmlSchemaNodeInfo: * * Holds information of an element node. */ struct _xmlSchemaNodeInfo { int nodeType; xmlNodePtr node; int nodeLine; const xmlChar *localName; const xmlChar *nsName; const xmlChar *value; xmlSchemaValPtr val; /* the pre-computed value if any */ xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ int flags; /* combination of node info flags */ int valNeeded; int normVal; xmlSchemaElementPtr decl; /* the element/attribute declaration */ int depth; xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings for the scope element*/ xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope element */ xmlRegExecCtxtPtr regexCtxt; const xmlChar **nsBindings; /* Namespace bindings on this element */ int nbNsBindings; int sizeNsBindings; int hasKeyrefs; int appliedXPath; /* Indicates that an XPath has been applied. */ }; #define XML_SCHEMAS_ATTR_UNKNOWN 1 #define XML_SCHEMAS_ATTR_ASSESSED 2 #define XML_SCHEMAS_ATTR_PROHIBITED 3 #define XML_SCHEMAS_ATTR_ERR_MISSING 4 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7 #define XML_SCHEMAS_ATTR_DEFAULT 8 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12 #define XML_SCHEMAS_ATTR_WILD_SKIP 13 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16 #define XML_SCHEMAS_ATTR_META 17 /* * @metaType values of xmlSchemaAttrInfo. */ #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo; typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr; struct _xmlSchemaAttrInfo { int nodeType; xmlNodePtr node; int nodeLine; const xmlChar *localName; const xmlChar *nsName; const xmlChar *value; xmlSchemaValPtr val; /* the pre-computed value if any */ xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ int flags; /* combination of node info flags */ xmlSchemaAttributePtr decl; /* the attribute declaration */ xmlSchemaAttributeUsePtr use; /* the attribute use */ int state; int metaType; const xmlChar *vcValue; /* the value constraint value */ xmlSchemaNodeInfoPtr parent; }; #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1 /** * xmlSchemaValidCtxt: * * A Schemas validation context */ struct _xmlSchemaValidCtxt { int type; void *errCtxt; /* user specific data block */ xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ xmlStructuredErrorFunc serror; xmlSchemaPtr schema; /* The schema in use */ xmlDocPtr doc; xmlParserInputBufferPtr input; xmlCharEncoding enc; xmlSAXHandlerPtr sax; xmlParserCtxtPtr parserCtxt; void *user_data; /* TODO: What is this for? */ int err; int nberrors; xmlNodePtr node; xmlNodePtr cur; /* xmlSchemaTypePtr type; */ xmlRegExecCtxtPtr regexp; xmlSchemaValPtr value; int valueWS; int options; xmlNodePtr validationRoot; xmlSchemaParserCtxtPtr pctxt; int xsiAssemble; int depth; xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */ int sizeElemInfos; xmlSchemaNodeInfoPtr inode; /* the current element information */ xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */ xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */ xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */ xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */ xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/ int nbIdcNodes; int sizeIdcNodes; xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */ int nbIdcKeys; int sizeIdcKeys; int flags; xmlDictPtr dict; #ifdef LIBXML_READER_ENABLED xmlTextReaderPtr reader; #endif xmlSchemaAttrInfoPtr *attrInfos; int nbAttrInfos; int sizeAttrInfos; int skipDepth; xmlSchemaItemListPtr nodeQNames; int hasKeyrefs; int createIDCNodeTables; int psviExposeIDCNodeTables; }; /** * xmlSchemaSubstGroup: * * */ typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup; typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr; struct _xmlSchemaSubstGroup { xmlSchemaElementPtr head; xmlSchemaItemListPtr members; }; /*static xmlSchemaQNameRefPtr xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, xmlNodePtr node);*/ #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_xpath_object.h0000644000004100000410000000052513760147770022664 0ustar www-datawww-data#ifndef __RXML_XPATH_OBJECT__ #define __RXML_XPATH_OBJECT__ extern VALUE cXMLXPathObject; typedef struct rxml_xpath_object { xmlDocPtr xdoc; xmlXPathObjectPtr xpop; VALUE nsnodes; } rxml_xpath_object; void rxml_init_xpath_object(void); VALUE rxml_xpath_object_wrap(xmlDocPtr xdoc, xmlXPathObjectPtr xpop); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_encoding.h0000644000004100000410000000101113760147770021767 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_ENCODING__ #define __RXML_ENCODING__ extern VALUE mXMLEncoding; void rxml_init_encoding(); VALUE rxml_new_cstr(const xmlChar* xstr, const xmlChar* xencoding); VALUE rxml_new_cstr_len(const xmlChar* xstr, const long length, const xmlChar* xencoding); rb_encoding* rxml_xml_encoding_to_rb_encoding(VALUE klass, xmlCharEncoding xmlEncoding); rb_encoding* rxml_figure_encoding(const xmlChar* xencoding); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_document.h0000644000004100000410000000042513760147770022027 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_DOCUMENT__ #define __RXML_DOCUMENT__ extern VALUE cXMLDocument; void rxml_init_document(); VALUE rxml_document_wrap(xmlDocPtr xnode); typedef xmlChar * xmlCharPtr; #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_schema_facet.h0000644000004100000410000000046413760147770022616 0ustar www-datawww-data#ifndef __RXML_SCHEMA_FACET__ #define __RXML_SCHEMA_FACET__ #include #include #include extern VALUE cXMLSchemaFacet; VALUE rxml_wrap_schema_facet(xmlSchemaFacetPtr facet); void rxml_init_schema_facet(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_error.h0000644000004100000410000000043413760147770021342 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_ERROR__ #define __RXML_ERROR__ extern VALUE eXMLError; void rxml_init_error(); VALUE rxml_error_wrap(xmlErrorPtr xerror); NORETURN(void rxml_raise(xmlErrorPtr xerror)); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_io.c0000644000004100000410000000230413760147770020611 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include "ruby_libxml.h" #include static ID READ_METHOD; static ID WRITE_METHOD; /* This method is called by libxml when it wants to read more data from a stream. We go with the duck typing solution to support StringIO objects. */ int rxml_read_callback(void *context, char *buffer, int len) { VALUE io = (VALUE) context; VALUE string = rb_funcall(io, READ_METHOD, 1, INT2NUM(len)); size_t size; if (string == Qnil) return 0; size = RSTRING_LEN(string); memcpy(buffer, StringValuePtr(string), size); return (int)size; } int rxml_write_callback(VALUE io, const char *buffer, int len) { if (rb_io_check_io(io) == Qnil) { // Could be StringIO VALUE written, string; string = rb_external_str_new_with_enc(buffer, strlen(buffer), rb_enc_get(io)); written = rb_funcall(io, WRITE_METHOD, 1, string); return NUM2INT(written); } else { return (int)rb_io_bufwrite(io, buffer, (size_t)len); } } void rxml_init_io(void) { READ_METHOD = rb_intern("read"); WRITE_METHOD = rb_intern("write"); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_schema_element.h0000644000004100000410000000054113760147770023161 0ustar www-datawww-data#ifndef __RXML_SCHEMA_ELEMENT__ #define __RXML_SCHEMA_ELEMENT__ #include "ruby_xml_schema.h" #include #include #include extern VALUE cXMLSchemaElement; VALUE rxml_wrap_schema_element(xmlSchemaElementPtr xelement); void rxml_init_schema_element(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_sax2_handler.c0000644000004100000410000002273013760147770022561 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include "ruby_libxml.h" #include "ruby_xml_sax2_handler.h" VALUE cbidOnCdataBlock; VALUE cbidOnCharacters; VALUE cbidOnComment; VALUE cbidOnEndDocument; VALUE cbidOnEndElement; VALUE cbidOnEndElementNs; VALUE cbidOnExternalSubset; VALUE cbidOnHasExternalSubset; VALUE cbidOnHasInternalSubset; VALUE cbidOnInternalSubset; VALUE cbidOnIsStandalone; VALUE cbidOnError; VALUE cbidOnProcessingInstruction; VALUE cbidOnReference; VALUE cbidOnStartElement; VALUE cbidOnStartElementNs; VALUE cbidOnStartDocument; /* ====== Callbacks =========== */ static void cdata_block_callback(void *ctx, const xmlChar *value, int len) { VALUE handler = (VALUE) ctx; if (handler != Qnil) { rb_funcall(handler, cbidOnCdataBlock,1, rxml_new_cstr_len(value, len, NULL)); } } static void characters_callback(void *ctx, const xmlChar *chars, int len) { VALUE handler = (VALUE) ctx; if (handler != Qnil) { VALUE rchars = rxml_new_cstr_len(chars, len, NULL); rb_funcall(handler, cbidOnCharacters, 1, rchars); } } static void comment_callback(void *ctx, const xmlChar *msg) { VALUE handler = (VALUE) ctx; if (handler != Qnil) { rb_funcall(handler, cbidOnComment, 1, rxml_new_cstr(msg, NULL)); } } static void end_document_callback(void *ctx) { VALUE handler = (VALUE) ctx; if (handler != Qnil) { rb_funcall(handler, cbidOnEndDocument, 0); } } static void end_element_ns_callback(void *ctx, const xmlChar *xlocalname, const xmlChar *xprefix, const xmlChar *xURI) { VALUE handler = (VALUE) ctx; if (handler == Qnil) return; /* Call end element for old-times sake */ if (rb_respond_to(handler, cbidOnEndElement)) { VALUE name; if (xprefix) { name = rxml_new_cstr(xprefix, NULL); rb_str_cat2(name, ":"); rb_str_cat2(name, (const char*)xlocalname); } else { name = rxml_new_cstr(xlocalname, NULL); } rb_funcall(handler, cbidOnEndElement, 1, name); } rb_funcall(handler, cbidOnEndElementNs, 3, rxml_new_cstr(xlocalname, NULL), xprefix ? rxml_new_cstr(xprefix, NULL) : Qnil, xURI ? rxml_new_cstr(xURI, NULL) : Qnil); } static void external_subset_callback(void *ctx, const xmlChar *name, const xmlChar *extid, const xmlChar *sysid) { VALUE handler = (VALUE) ctx; if (handler != Qnil) { VALUE rname = name ? rxml_new_cstr(name, NULL) : Qnil; VALUE rextid = extid ? rxml_new_cstr(extid, NULL) : Qnil; VALUE rsysid = sysid ? rxml_new_cstr(sysid, NULL) : Qnil; rb_funcall(handler, cbidOnExternalSubset, 3, rname, rextid, rsysid); } } static void has_external_subset_callback(void *ctx) { VALUE handler = (VALUE) ctx; if (handler != Qnil) { rb_funcall(handler, cbidOnHasExternalSubset, 0); } } static void has_internal_subset_callback(void *ctx) { VALUE handler = (VALUE) ctx; if (handler != Qnil) { rb_funcall(handler, cbidOnHasInternalSubset, 0); } } static void internal_subset_callback(void *ctx, const xmlChar *name, const xmlChar *extid, const xmlChar *sysid) { VALUE handler = (VALUE) ctx; if (handler != Qnil) { VALUE rname = name ? rxml_new_cstr(name, NULL) : Qnil; VALUE rextid = extid ? rxml_new_cstr(extid, NULL) : Qnil; VALUE rsysid = sysid ? rxml_new_cstr(sysid, NULL) : Qnil; rb_funcall(handler, cbidOnInternalSubset, 3, rname, rextid, rsysid); } } static void is_standalone_callback(void *ctx) { VALUE handler = (VALUE) ctx; if (handler != Qnil) { rb_funcall(handler, cbidOnIsStandalone,0); } } static void processing_instruction_callback(void *ctx, const xmlChar *target, const xmlChar *data) { VALUE handler = (VALUE) ctx; if (handler != Qnil) { VALUE rtarget = target ? rxml_new_cstr(target, NULL) : Qnil; VALUE rdata = data ? rxml_new_cstr(data, NULL) : Qnil; rb_funcall(handler, cbidOnProcessingInstruction, 2, rtarget, rdata); } } static void reference_callback(void *ctx, const xmlChar *name) { VALUE handler = (VALUE) ctx; if (handler != Qnil) { rb_funcall(handler, cbidOnReference, 1, rxml_new_cstr(name, NULL)); } } static void start_document_callback(void *ctx) { VALUE handler = (VALUE) ctx; if (handler != Qnil) { rb_funcall(handler, cbidOnStartDocument, 0); } } static void start_element_ns_callback(void *ctx, const xmlChar *xlocalname, const xmlChar *xprefix, const xmlChar *xURI, int nb_namespaces, const xmlChar **xnamespaces, int nb_attributes, int nb_defaulted, const xmlChar **xattributes) { VALUE handler = (VALUE) ctx; VALUE attributes = rb_hash_new(); VALUE namespaces = rb_hash_new(); if (handler == Qnil) return; if (xattributes) { /* Each attribute is an array of [localname, prefix, URI, value, end] */ int i; for (i = 0;i < nb_attributes * 5; i+=5) { VALUE attrName = rxml_new_cstr(xattributes[i+0], NULL); long attrLen = (long)(xattributes[i+4] - xattributes[i+3]); VALUE attrValue = rxml_new_cstr_len(xattributes[i+3], attrLen, NULL); rb_hash_aset(attributes, attrName, attrValue); } } if (xnamespaces) { int i; for (i = 0;i < nb_namespaces * 2; i+=2) { VALUE nsPrefix = xnamespaces[i+0] ? rxml_new_cstr(xnamespaces[i+0], NULL) : Qnil; VALUE nsURI = xnamespaces[i+1] ? rxml_new_cstr(xnamespaces[i+1], NULL) : Qnil; rb_hash_aset(namespaces, nsPrefix, nsURI); } } /* Call start element for old-times sake */ if (rb_respond_to(handler, cbidOnStartElement)) { VALUE name; if (xprefix) { name = rxml_new_cstr(xprefix, NULL); rb_str_cat2(name, ":"); rb_str_cat2(name, (const char*)xlocalname); } else { name = rxml_new_cstr(xlocalname, NULL); } rb_funcall(handler, cbidOnStartElement, 2, name, attributes); } rb_funcall(handler, cbidOnStartElementNs, 5, rxml_new_cstr(xlocalname, NULL), attributes, xprefix ? rxml_new_cstr(xprefix, NULL) : Qnil, xURI ? rxml_new_cstr(xURI, NULL) : Qnil, namespaces); } static void structured_error_callback(void *ctx, xmlErrorPtr xerror) { /* Older versions of Libxml will pass a NULL context from the sax parser. Fixed on Feb 23, 2011. See: http://git.gnome.org/browse/libxml2/commit/?id=241d4a1069e6bedd0ee2295d7b43858109c1c6d1 */ VALUE handler; #if LIBXML_VERSION <= 20708 xmlParserCtxtPtr ctxt = (xmlParserCtxt*)(xerror->ctxt); ctx = ctxt->userData; #endif handler = (VALUE) ctx; if (handler != Qnil) { VALUE error = rxml_error_wrap(xerror); rb_funcall(handler, cbidOnError, 1, error); } } /* ====== Handler =========== */ xmlSAXHandler rxml_sax_handler = { (internalSubsetSAXFunc) internal_subset_callback, (isStandaloneSAXFunc) is_standalone_callback, (hasInternalSubsetSAXFunc) has_internal_subset_callback, (hasExternalSubsetSAXFunc) has_external_subset_callback, 0, /* resolveEntity */ 0, /* getEntity */ 0, /* entityDecl */ 0, /* notationDecl */ 0, /* attributeDecl */ 0, /* elementDecl */ 0, /* unparsedEntityDecl */ 0, /* setDocumentLocator */ (startDocumentSAXFunc) start_document_callback, (endDocumentSAXFunc) end_document_callback, 0, /* Use start_element_ns_callback instead */ 0, /* Use end_element_ns_callback instead */ (referenceSAXFunc) reference_callback, (charactersSAXFunc) characters_callback, 0, /* ignorableWhitespace */ (processingInstructionSAXFunc) processing_instruction_callback, (commentSAXFunc) comment_callback, 0, /* xmlStructuredErrorFunc is used instead */ 0, /* xmlStructuredErrorFunc is used instead */ 0, /* xmlStructuredErrorFunc is used instead */ 0, /* xmlGetParameterEntity */ (cdataBlockSAXFunc) cdata_block_callback, (externalSubsetSAXFunc) external_subset_callback, XML_SAX2_MAGIC, /* force SAX2 */ 0, /* _private */ (startElementNsSAX2Func) start_element_ns_callback, (endElementNsSAX2Func) end_element_ns_callback, (xmlStructuredErrorFunc) structured_error_callback }; void rxml_init_sax2_handler(void) { /* SaxCallbacks */ cbidOnCdataBlock = rb_intern("on_cdata_block"); cbidOnCharacters = rb_intern("on_characters"); cbidOnComment = rb_intern("on_comment"); cbidOnEndDocument = rb_intern("on_end_document"); cbidOnEndElement = rb_intern("on_end_element"); cbidOnEndElementNs = rb_intern("on_end_element_ns"); cbidOnError = rb_intern("on_error"); cbidOnExternalSubset = rb_intern("on_external_subset"); cbidOnHasExternalSubset = rb_intern("on_has_external_subset"); cbidOnHasInternalSubset = rb_intern("on_has_internal_subset"); cbidOnInternalSubset = rb_intern("on_internal_subset"); cbidOnIsStandalone = rb_intern("on_is_standalone"); cbidOnProcessingInstruction = rb_intern("on_processing_instruction"); cbidOnReference = rb_intern("on_reference"); cbidOnStartElement = rb_intern("on_start_element"); cbidOnStartElementNs = rb_intern("on_start_element_ns"); cbidOnStartDocument = rb_intern("on_start_document"); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_encoding.c0000644000004100000410000002023113760147770021767 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include #include "ruby_libxml.h" /* * Document-class: LibXML::XML::Encoding * * The encoding class exposes the encodings that libxml * supports via constants. * * LibXML converts all data sources to UTF8 * internally before processing them. By default, * LibXML determines a data source's encoding * using the algorithm described on its * website[http://xmlsoft.org/encoding.html]. * * However, you may override a data source's encoding * by using the encoding constants defined in this * module. * * Example 1: * * io = File.open('some_file', 'rb') * parser = XML::Parser.io(io, :encoding => XML::Encoding::ISO_8859_1) * doc = parser.parse * * Example 2: * * parser = XML::HTMLParser.file("some_file", :encoding => XML::Encoding::ISO_8859_1) * doc = parser.parse * * Example 3: * * document = XML::Document.new * document.encoding = XML::Encoding::ISO_8859_1 * doc << XML::Node.new */ VALUE mXMLEncoding; /* * call-seq: * Encoding.from_s("UTF_8") -> XML::Encoding::UTF_8 * * Converts an encoding string to an encoding constant * defined on the XML::Encoding class. */ static VALUE rxml_encoding_from_s(VALUE klass, VALUE encoding) { xmlCharEncoding xencoding; if (encoding == Qnil) return Qnil; xencoding = xmlParseCharEncoding(StringValuePtr(encoding)); return INT2NUM(xencoding); } /* * call-seq: * Encoding.to_s(XML::Encoding::UTF_8) -> "UTF-8" * * Converts an encoding constant defined on the XML::Encoding * class to its text representation. */ static VALUE rxml_encoding_to_s(VALUE klass, VALUE encoding) { const xmlChar* xencoding = (const xmlChar*)xmlGetCharEncodingName(NUM2INT(encoding)); if (!xencoding) return Qnil; else return rxml_new_cstr(xencoding, xencoding); } /* * Converts an xmlCharEncoding enum value into a Ruby Encoding object (available * on Ruby 1.9.* and higher). */ rb_encoding* rxml_xml_encoding_to_rb_encoding(VALUE klass, xmlCharEncoding xmlEncoding) { const char* encodingName; switch (xmlEncoding) { case XML_CHAR_ENCODING_UTF8: encodingName = "UTF-8"; break; case XML_CHAR_ENCODING_UTF16LE: encodingName = "UTF-16LE"; break; case XML_CHAR_ENCODING_UTF16BE: encodingName = "UTF-16BE"; break; case XML_CHAR_ENCODING_UCS4LE: encodingName = "UCS-4LE"; break; case XML_CHAR_ENCODING_UCS4BE: encodingName = "UCS-4BE"; break; case XML_CHAR_ENCODING_UCS2: encodingName = "UCS-2"; break; case XML_CHAR_ENCODING_8859_1: encodingName = "ISO8859-1"; break; case XML_CHAR_ENCODING_8859_2: encodingName = "ISO8859-2"; break; case XML_CHAR_ENCODING_8859_3: encodingName = "ISO8859-3"; break; case XML_CHAR_ENCODING_8859_4: encodingName = "ISO8859-4"; break; case XML_CHAR_ENCODING_8859_5: encodingName = "ISO8859-5"; break; case XML_CHAR_ENCODING_8859_6: encodingName = "ISO8859-6"; break; case XML_CHAR_ENCODING_8859_7: encodingName = "ISO8859-7"; break; case XML_CHAR_ENCODING_8859_8: encodingName = "ISO8859-8"; break; case XML_CHAR_ENCODING_8859_9: encodingName = "ISO8859-9"; break; case XML_CHAR_ENCODING_2022_JP: encodingName = "ISO-2022-JP"; break; case XML_CHAR_ENCODING_SHIFT_JIS: encodingName = "SHIFT-JIS"; break; case XML_CHAR_ENCODING_EUC_JP: encodingName = "EUC-JP"; break; case XML_CHAR_ENCODING_ASCII: encodingName = "US-ASCII"; break; default: /* Covers XML_CHAR_ENCODING_ERROR, XML_CHAR_ENCODING_NONE, XML_CHAR_ENCODING_EBCDIC */ encodingName = "ASCII-8BIT"; break; } return rb_enc_find(encodingName); } /* * call-seq: * Input.encoding_to_rb_encoding(Input::ENCODING) -> Encoding * * Converts an encoding constant defined on the XML::Encoding * class to a Ruby encoding object (available on Ruby 1.9.* and higher). */ VALUE rxml_encoding_to_rb_encoding(VALUE klass, VALUE encoding) { xmlCharEncoding xmlEncoding = (xmlCharEncoding)NUM2INT(encoding); rb_encoding* rbencoding = rxml_xml_encoding_to_rb_encoding(klass, xmlEncoding); return rb_enc_from_encoding(rbencoding); } rb_encoding* rxml_figure_encoding(const xmlChar* xencoding) { rb_encoding* result; if (xencoding) { xmlCharEncoding xmlEncoding = xmlParseCharEncoding((const char*)xencoding); result = rxml_xml_encoding_to_rb_encoding(mXMLEncoding, xmlEncoding); } else { result = rb_utf8_encoding(); } return result; } VALUE rxml_new_cstr(const xmlChar* xstr, const xmlChar* xencoding) { rb_encoding *rbencoding = rxml_figure_encoding(xencoding); return rb_external_str_new_with_enc((const char*)xstr, strlen((const char*)xstr), rbencoding); } VALUE rxml_new_cstr_len(const xmlChar* xstr, const long length, const xmlChar* xencoding) { rb_encoding *rbencoding = rxml_figure_encoding(xencoding); return rb_external_str_new_with_enc((const char*)xstr, length, rbencoding); } void rxml_init_encoding(void) { mXMLEncoding = rb_define_module_under(mXML, "Encoding"); rb_define_module_function(mXMLEncoding, "from_s", rxml_encoding_from_s, 1); rb_define_module_function(mXMLEncoding, "to_s", rxml_encoding_to_s, 1); rb_define_module_function(mXMLEncoding, "to_rb_encoding", rxml_encoding_to_rb_encoding, 2); /* -1: No char encoding detected. */ rb_define_const(mXMLEncoding, "ERROR", INT2NUM(XML_CHAR_ENCODING_ERROR)); /* 0: No char encoding detected. */ rb_define_const(mXMLEncoding, "NONE", INT2NUM(XML_CHAR_ENCODING_NONE)); /* 1: UTF-8 */ rb_define_const(mXMLEncoding, "UTF_8", INT2NUM(XML_CHAR_ENCODING_UTF8)); /* 2: UTF-16 little endian. */ rb_define_const(mXMLEncoding, "UTF_16LE", INT2NUM(XML_CHAR_ENCODING_UTF16LE)); /* 3: UTF-16 big endian. */ rb_define_const(mXMLEncoding, "UTF_16BE", INT2NUM(XML_CHAR_ENCODING_UTF16BE)); /* 4: UCS-4 little endian. */ rb_define_const(mXMLEncoding, "UCS_4LE", INT2NUM(XML_CHAR_ENCODING_UCS4LE)); /* 5: UCS-4 big endian. */ rb_define_const(mXMLEncoding, "UCS_4BE", INT2NUM(XML_CHAR_ENCODING_UCS4BE)); /* 6: EBCDIC uh! */ rb_define_const(mXMLEncoding, "EBCDIC", INT2NUM(XML_CHAR_ENCODING_EBCDIC)); /* 7: UCS-4 unusual ordering. */ rb_define_const(mXMLEncoding, "UCS_4_2143", INT2NUM(XML_CHAR_ENCODING_UCS4_2143)); /* 8: UCS-4 unusual ordering. */ rb_define_const(mXMLEncoding, "UCS_4_3412", INT2NUM(XML_CHAR_ENCODING_UCS4_3412)); /* 9: UCS-2. */ rb_define_const(mXMLEncoding, "UCS_2", INT2NUM(XML_CHAR_ENCODING_UCS2)); /* 10: ISO-8859-1 ISO Latin 1. */ rb_define_const(mXMLEncoding, "ISO_8859_1", INT2NUM(XML_CHAR_ENCODING_8859_1)); /* 11: ISO-8859-2 ISO Latin 2. */ rb_define_const(mXMLEncoding, "ISO_8859_2", INT2NUM(XML_CHAR_ENCODING_8859_2)); /* 12: ISO-8859-3. */ rb_define_const(mXMLEncoding, "ISO_8859_3", INT2NUM(XML_CHAR_ENCODING_8859_3)); /* 13: ISO-8859-4. */ rb_define_const(mXMLEncoding, "ISO_8859_4", INT2NUM(XML_CHAR_ENCODING_8859_4)); /* 14: ISO-8859-5. */ rb_define_const(mXMLEncoding, "ISO_8859_5", INT2NUM(XML_CHAR_ENCODING_8859_5)); /* 15: ISO-8859-6. */ rb_define_const(mXMLEncoding, "ISO_8859_6", INT2NUM(XML_CHAR_ENCODING_8859_6)); /* 16: ISO-8859-7. */ rb_define_const(mXMLEncoding, "ISO_8859_7", INT2NUM(XML_CHAR_ENCODING_8859_7)); /* 17: ISO-8859-8. */ rb_define_const(mXMLEncoding, "ISO_8859_8", INT2NUM(XML_CHAR_ENCODING_8859_8)); /* 18: ISO-8859-9. */ rb_define_const(mXMLEncoding, "ISO_8859_9", INT2NUM(XML_CHAR_ENCODING_8859_9)); /* 19: ISO-2022-JP. */ rb_define_const(mXMLEncoding, "ISO_2022_JP", INT2NUM(XML_CHAR_ENCODING_2022_JP)); /* 20: Shift_JIS. */ rb_define_const(mXMLEncoding, "SHIFT_JIS", INT2NUM(XML_CHAR_ENCODING_SHIFT_JIS)); /* 21: EUC-JP. */ rb_define_const(mXMLEncoding, "EUC_JP", INT2NUM(XML_CHAR_ENCODING_EUC_JP)); /* 22: pure ASCII. */ rb_define_const(mXMLEncoding, "ASCII", INT2NUM(XML_CHAR_ENCODING_ASCII)); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_namespace.h0000644000004100000410000000037413760147770022150 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_NAMESPACE__ #define __RXML_NAMESPACE__ extern VALUE cXMLNamespace; void rxml_init_namespace(void); VALUE rxml_namespace_wrap(xmlNsPtr xns); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_cbg.c0000644000004100000410000000416113760147770020740 0ustar www-datawww-data#include "ruby_libxml.h" #include #include /* int xmlRegisterInputCallbacks (xmlInputMatchCallback matchFunc, xmlInputOpenCallback openFunc, xmlInputReadCallback readFunc, xmlInputCloseCallback closeFunc); int (*xmlInputMatchCallback) (char const *filename); void* (*xmlInputOpenCallback) (char const *filename); int (*xmlInputReadCallback) (void *context, char *buffer, int len); int (*xmlInputCloseCallback) (void *context); */ typedef struct deb_doc_context { char *buffer; char *bpos; int remaining; } deb_doc_context; int deb_Match(char const *filename) { fprintf(stderr, "deb_Match: %s\n", filename); if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "deb://", 6)) { return (1); } return (0); } void* deb_Open(char const *filename) { deb_doc_context *deb_doc; VALUE res; deb_doc = (deb_doc_context*) malloc(sizeof(deb_doc_context)); res = rb_funcall(rb_funcall(rb_mKernel, rb_intern("const_get"), 1, rb_str_new2("DEBSystem")), rb_intern("document_query"), 1, rb_str_new2(filename)); deb_doc->buffer = strdup(StringValuePtr(res)); //deb_doc->buffer = strdup("serepes"); deb_doc->bpos = deb_doc->buffer; deb_doc->remaining = (int)strlen(deb_doc->buffer); return deb_doc; } int deb_Read(void *context, char *buffer, int len) { deb_doc_context *deb_doc; int ret_len; deb_doc = (deb_doc_context*) context; if (len >= deb_doc->remaining) { ret_len = deb_doc->remaining; } else { ret_len = len; } deb_doc->remaining -= ret_len; strncpy(buffer, deb_doc->bpos, ret_len); deb_doc->bpos += ret_len; return ret_len; } int deb_Close(void *context) { free(((deb_doc_context*) context)->buffer); free(context); return 1; } void deb_register_cbg() { xmlRegisterInputCallbacks(deb_Match, deb_Open, deb_Read, deb_Close); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_html_parser.h0000644000004100000410000000033313760147770022527 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_HTML_PARSER__ #define __RXML_HTML_PARSER__ extern VALUE cXMLHtmlParser; void rxml_init_html_parser(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_attributes.h0000644000004100000410000000063113760147770022376 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_ATTRIBUTES__ #define __RXML_ATTRIBUTES__ extern VALUE cXMLAttributesibutes; void rxml_init_attributes(void); VALUE rxml_attributes_new(xmlNodePtr xnode); VALUE rxml_attributes_attribute_get(VALUE self, VALUE name); VALUE rxml_attributes_attribute_set(VALUE self, VALUE name, VALUE value); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_schema_attribute.h0000644000004100000410000000055613760147770023541 0ustar www-datawww-data#ifndef __RXML_SCHEMA_ATTRIBUTE__ #define __RXML_SCHEMA_ATTRIBUTE__ #include "ruby_xml_schema.h" #include #include #include extern VALUE cXMLSchemaAttribute; void rxml_init_schema_attribute(void); VALUE rxml_wrap_schema_attribute(xmlSchemaAttributeUsePtr attr); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_dtd.c0000644000004100000410000001473613760147770020771 0ustar www-datawww-data#include "ruby_libxml.h" #include "ruby_xml_dtd.h" /* * Document-class: LibXML::XML::Dtd * * The XML::Dtd class is used to prepare DTD's for validation of xml * documents. * * DTDs can be created from a string or a pair of public and system identifiers. * Once a Dtd object is instantiated, an XML document can be validated by the * XML::Document#validate method providing the XML::Dtd object as parameeter. * The method will raise an exception if the document is * not valid. * * Basic usage: * * # parse DTD * dtd = XML::Dtd.new(< * * EOF * * # parse xml document to be validated * instance = XML::Document.file('instance.xml') * * # validate * instance.validate(dtd) */ VALUE cXMLDtd; void rxml_dtd_free(xmlDtdPtr xdtd) { if (xdtd->doc == NULL && xdtd->parent == NULL) xmlFreeDtd(xdtd); } void rxml_dtd_mark(xmlDtdPtr xdtd) { if (xdtd && xdtd->doc) { VALUE doc = (VALUE)xdtd->doc->_private; rb_gc_mark(doc); } } static VALUE rxml_dtd_alloc(VALUE klass) { return Data_Wrap_Struct(klass, rxml_dtd_mark, rxml_dtd_free, NULL); } VALUE rxml_dtd_wrap(xmlDtdPtr xdtd) { return Data_Wrap_Struct(cXMLDtd, NULL, NULL, xdtd); } /* * call-seq: * dtd.external_id -> "string" * * Obtain this dtd's external identifer (for a PUBLIC DTD). */ static VALUE rxml_dtd_external_id_get(VALUE self) { xmlDtdPtr xdtd; Data_Get_Struct(self, xmlDtd, xdtd); if (xdtd->ExternalID == NULL) return (Qnil); else return (rxml_new_cstr( xdtd->ExternalID, NULL)); } /* * call-seq: * dtd.name -> "string" * * Obtain this dtd's name. */ static VALUE rxml_dtd_name_get(VALUE self) { xmlDtdPtr xdtd; Data_Get_Struct(self, xmlDtd, xdtd); if (xdtd->name == NULL) return (Qnil); else return (rxml_new_cstr( xdtd->name, NULL)); } /* * call-seq: * dtd.uri -> "string" * * Obtain this dtd's URI (for a SYSTEM or PUBLIC DTD). */ static VALUE rxml_dtd_uri_get(VALUE self) { xmlDtdPtr xdtd; Data_Get_Struct(self, xmlDtd, xdtd); if (xdtd->SystemID == NULL) return (Qnil); else return (rxml_new_cstr( xdtd->SystemID, NULL)); } /* * call-seq: * node.type -> num * * Obtain this node's type identifier. */ static VALUE rxml_dtd_type(VALUE self) { xmlDtdPtr xdtd; Data_Get_Struct(self, xmlDtd, xdtd); return (INT2NUM(xdtd->type)); } /* * call-seq: * XML::Dtd.new("DTD string") -> dtd * XML::Dtd.new("public", "system") -> dtd * XML::Dtd.new("name", "public", "system", document) -> external subset dtd * XML::Dtd.new("name", "public", "system", document, false) -> internal subset dtd * XML::Dtd.new("name", "public", "system", document, true) -> internal subset dtd * * Create a new Dtd from the specified public and system * identifiers. */ static VALUE rxml_dtd_initialize(int argc, VALUE *argv, VALUE self) { VALUE external, system, dtd_string; xmlParserInputBufferPtr buffer; xmlCharEncoding enc = XML_CHAR_ENCODING_NONE; xmlChar *new_string; xmlDtdPtr xdtd; // 1 argument -- string --> parsujeme jako dtd // 2 arguments -- public, system --> bude se hledat // 3 arguments -- public, system, name --> creates an external subset (any parameter may be nil) // 4 arguments -- public, system, name, doc --> creates an external subset (any parameter may be nil) // 5 arguments -- public, system, name, doc, true --> creates an internal subset (all but last parameter may be nil) switch (argc) { case 3: case 4: case 5: { VALUE name, doc, internal; const xmlChar *xname = NULL, *xpublic = NULL, *xsystem = NULL; xmlDocPtr xdoc = NULL; rb_scan_args(argc, argv, "32", &external, &system, &name, &doc, &internal); if (external != Qnil) { Check_Type(external, T_STRING); xpublic = (const xmlChar*) StringValuePtr(external); } if (system != Qnil) { Check_Type(system, T_STRING); xsystem = (const xmlChar*) StringValuePtr(system); } if (name != Qnil) { Check_Type(name, T_STRING); xname = (const xmlChar*) StringValuePtr(name); } if (doc != Qnil) { if (rb_obj_is_kind_of(doc, cXMLDocument) == Qfalse) rb_raise(rb_eTypeError, "Must pass an LibXML::XML::Document object"); Data_Get_Struct(doc, xmlDoc, xdoc); } if (internal == Qnil || internal == Qfalse) xdtd = xmlNewDtd(xdoc, xname, xpublic, xsystem); else xdtd = xmlCreateIntSubset(xdoc, xname, xpublic, xsystem); if (xdtd == NULL) rxml_raise(&xmlLastError); /* Document will free this dtd now. */ RDATA(self)->dfree = NULL; DATA_PTR(self) = xdtd; xmlSetTreeDoc((xmlNodePtr) xdtd, xdoc); } break; case 2: rb_scan_args(argc, argv, "20", &external, &system); Check_Type(external, T_STRING); Check_Type(system, T_STRING); xdtd = xmlParseDTD((xmlChar*) StringValuePtr(external), (xmlChar*) StringValuePtr(system)); if (xdtd == NULL) rxml_raise(&xmlLastError); DATA_PTR(self) = xdtd; xmlSetTreeDoc((xmlNodePtr) xdtd, NULL); break; case 1: rb_scan_args(argc, argv, "10", &dtd_string); Check_Type(dtd_string, T_STRING); /* Note that buffer is freed by xmlParserInputBufferPush*/ buffer = xmlAllocParserInputBuffer(enc); new_string = xmlStrdup((xmlChar*) StringValuePtr(dtd_string)); xmlParserInputBufferPush(buffer, xmlStrlen(new_string), (const char*) new_string); xdtd = xmlIOParseDTD(NULL, buffer, enc); if (xdtd == NULL) rxml_raise(&xmlLastError); xmlFree(new_string); DATA_PTR(self) = xdtd; break; default: rb_raise(rb_eArgError, "wrong number of arguments"); } return self; } void rxml_init_dtd() { cXMLDtd = rb_define_class_under(mXML, "Dtd", rb_cObject); rb_define_alloc_func(cXMLDtd, rxml_dtd_alloc); rb_define_method(cXMLDtd, "initialize", rxml_dtd_initialize, -1); rb_define_method(cXMLDtd, "external_id", rxml_dtd_external_id_get, 0); rb_define_method(cXMLDtd, "name", rxml_dtd_name_get, 0); rb_define_method(cXMLDtd, "uri", rxml_dtd_uri_get, 0); rb_define_method(cXMLDtd, "node_type", rxml_dtd_type, 0); rb_define_alias(cXMLDtd, "system_id", "uri"); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_node.c0000644000004100000410000011111113760147770021124 0ustar www-datawww-data#include "ruby_libxml.h" #include "ruby_xml_node.h" #include VALUE cXMLNode; /* Document-class: LibXML::XML::Node * * Nodes are the primary objects that make up an XML document. * The node class represents most node types that are found in * an XML document (but not LibXML::XML::Attributes, see LibXML::XML::Attr). * It exposes libxml's full API for creating, querying * moving and deleting node objects. Many of these methods are * documented in the DOM Level 3 specification found at: * http://www.w3.org/TR/DOM-Level-3-Core/. */ /* Memory management: * * The bindings create a one-to-one mapping between ruby objects and * libxml documents and libxml parent nodes (ie, nodes that do not * have a parent and do not belong to a document). In these cases, * the bindings manage the memory. They do this by installing a free * function and storing a back pointer to the Ruby object from the xmlnode * using the _private member on libxml structures. When the Ruby object * goes out of scope, the underlying libxml structure is freed. Libxml * itself then frees all child node (recursively). * * For all other nodes (the vast majority), the bindings create temporary * Ruby objects that get freed once they go out of scope. Thus there can be * more than one ruby object pointing to the same xml node. To mostly hide * this from programmers on the ruby side, the #eql? and #== methods are * overriden to check if two ruby objects wrap the same xmlnode. If they do, * then the methods return true. During the mark phase, each of these temporary * objects marks its owning document, thereby keeping the Ruby document object * alive and thus the xmldoc tree. * * In the sweep phase of the garbage collector, or when a program ends, * there is no order to how Ruby objects are freed. In fact, the ruby document * object is almost always freed before any ruby objects that wrap child nodes. * However, this is ok because those ruby objects do not have a free function * and are no longer in scope (since if they were the document would not be freed). */ static void rxml_node_free(xmlNodePtr xnode) { /* The ruby object wrapping the xml object no longer exists and this is a standalone node without a document or parent so ruby is responsible for freeing the underlying node.*/ if (xnode->doc == NULL && xnode->parent == NULL) { // Remove the back linkage from libxml to Ruby xnode->_private = NULL; xmlFreeNode(xnode); } } void rxml_node_manage(xmlNodePtr xnode, VALUE node) { RDATA(node)->dfree = (RUBY_DATA_FUNC)rxml_node_free; xnode->_private = (void*)node; } void rxml_node_unmanage(xmlNodePtr xnode, VALUE node) { RDATA(node)->dfree = NULL; xnode->_private = NULL; } xmlNodePtr rxml_node_root(xmlNodePtr xnode) { xmlNodePtr current = xnode; while (current->parent) { current = current->parent; } return current; } void rxml_node_mark(xmlNodePtr xnode) { if (xnode->doc) { if (xnode->doc->_private) { VALUE doc = (VALUE)xnode->doc->_private; rb_gc_mark(doc); } } else if (xnode->parent) { xmlNodePtr root = rxml_node_root(xnode); if (root->_private) { VALUE node = (VALUE)root->_private; rb_gc_mark(node); } } } VALUE rxml_node_wrap(xmlNodePtr xnode) { VALUE result = Qnil; // Is this node already wrapped? if (xnode->_private) { result = (VALUE)xnode->_private; } else { result = Data_Wrap_Struct(cXMLNode, rxml_node_mark, NULL, xnode); } if (!xnode->doc && !xnode->parent) { rxml_node_manage(xnode, result); } return result; } static VALUE rxml_node_alloc(VALUE klass) { // This node was created from Ruby so we are responsible for freeing it not libxml return Data_Wrap_Struct(klass, rxml_node_mark, rxml_node_free, NULL); } static xmlNodePtr rxml_get_xnode(VALUE node) { xmlNodePtr result; Data_Get_Struct(node, xmlNode, result); if (!result) rb_raise(rb_eRuntimeError, "This node has already been freed."); return result; } /* * call-seq: * XML::Node.new_cdata(content = nil) -> XML::Node * * Create a new #CDATA node, optionally setting * the node's content. */ static VALUE rxml_node_new_cdata(int argc, VALUE *argv, VALUE klass) { VALUE content = Qnil; xmlNodePtr xnode; rb_scan_args(argc, argv, "01", &content); if (NIL_P(content)) { xnode = xmlNewCDataBlock(NULL, NULL, 0); } else { content = rb_obj_as_string(content); xnode = xmlNewCDataBlock(NULL, (xmlChar*) StringValuePtr(content), (int)RSTRING_LEN(content)); } if (xnode == NULL) rxml_raise(&xmlLastError); return rxml_node_wrap(xnode); } /* * call-seq: * XML::Node.new_comment(content = nil) -> XML::Node * * Create a new comment node, optionally setting * the node's content. * */ static VALUE rxml_node_new_comment(int argc, VALUE *argv, VALUE klass) { VALUE content = Qnil; xmlNodePtr xnode; rb_scan_args(argc, argv, "01", &content); if (NIL_P(content)) { xnode = xmlNewComment(NULL); } else { content = rb_obj_as_string(content); xnode = xmlNewComment((xmlChar*) StringValueCStr(content)); } if (xnode == NULL) rxml_raise(&xmlLastError); return rxml_node_wrap(xnode); } /* * call-seq: * XML::Node.new_pi(name, content = nil) -> XML::Node * * Create a new pi node, optionally setting * the node's content. * */ static VALUE rxml_node_new_pi(int argc, VALUE *argv, VALUE klass) { VALUE name = Qnil; VALUE content = Qnil; xmlNodePtr xnode; rb_scan_args(argc, argv, "11", &name, &content); if (NIL_P(name)) { rb_raise(rb_eRuntimeError, "You must provide me with a name for a PI."); } name = rb_obj_as_string(name); if (NIL_P(content)) { xnode = xmlNewPI((xmlChar*) StringValuePtr(name), NULL); } else { content = rb_obj_as_string(content); xnode = xmlNewPI((xmlChar*) StringValuePtr(name), (xmlChar*) StringValueCStr(content)); } if (xnode == NULL) rxml_raise(&xmlLastError); return rxml_node_wrap(xnode); } /* * call-seq: * XML::Node.new_text(content) -> XML::Node * * Create a new text node. * */ static VALUE rxml_node_new_text(VALUE klass, VALUE content) { xmlNodePtr xnode; Check_Type(content, T_STRING); content = rb_obj_as_string(content); xnode = xmlNewText((xmlChar*) StringValueCStr(content)); if (xnode == NULL) rxml_raise(&xmlLastError); return rxml_node_wrap(xnode); } static VALUE rxml_node_content_set(VALUE self, VALUE content); /* * call-seq: * XML::Node.initialize(name, content = nil, namespace = nil) -> XML::Node * * Creates a new element with the specified name, content and * namespace. The content and namespace may be nil. */ static VALUE rxml_node_initialize(int argc, VALUE *argv, VALUE self) { VALUE name; VALUE content; VALUE ns; xmlNodePtr xnode = NULL; xmlNsPtr xns = NULL; rb_scan_args(argc, argv, "12", &name, &content, &ns); name = rb_obj_as_string(name); if (!NIL_P(ns)) Data_Get_Struct(ns, xmlNs, xns); xnode = xmlNewNode(xns, (xmlChar*) StringValuePtr(name)); if (xnode == NULL) rxml_raise(&xmlLastError); // Link the ruby wrapper to the underlying libxml node RDATA(self)->data = xnode; // Ruby is in charge of managing this node's memory rxml_node_manage(xnode, self); if (!NIL_P(content)) rxml_node_content_set(self, content); return self; } static VALUE rxml_node_modify_dom(VALUE self, VALUE target, xmlNodePtr (*xmlFunc)(xmlNodePtr, xmlNodePtr)) { xmlNodePtr xnode, xtarget, xresult; if (rb_obj_is_kind_of(target, cXMLNode) == Qfalse) rb_raise(rb_eTypeError, "Must pass an XML::Node object"); xnode = rxml_get_xnode(self); xtarget = rxml_get_xnode(target); if (xtarget->doc != NULL && xtarget->doc != xnode->doc) rb_raise(eXMLError, "Nodes belong to different documents. You must first import the node by calling LibXML::XML::Document.import"); xmlUnlinkNode(xtarget); // Target is about to have a parent, so stop having ruby manage it. rxml_node_unmanage(xtarget, target); // This target node could be freed here and be replaced by a different node xresult = xmlFunc(xnode, xtarget); if (!xresult) rxml_raise(&xmlLastError); /* Assume the target was freed, we need to fix up the ruby object to point to the newly returned node. */ RDATA(target)->data = xresult; return target; } /* * call-seq: * node.base_uri -> "uri" * * Obtain this node's base URI. */ static VALUE rxml_node_base_uri_get(VALUE self) { xmlNodePtr xnode; xmlChar* base_uri; VALUE result = Qnil; xnode = rxml_get_xnode(self); if (xnode->doc == NULL) return (result); base_uri = xmlNodeGetBase(xnode->doc, xnode); if (base_uri) { result = rxml_new_cstr( base_uri, NULL); xmlFree(base_uri); } return (result); } // TODO node_base_set should support setting back to nil /* * call-seq: * node.base_uri = "uri" * * Set this node's base URI. */ static VALUE rxml_node_base_uri_set(VALUE self, VALUE uri) { xmlNodePtr xnode; Check_Type(uri, T_STRING); xnode = rxml_get_xnode(self); if (xnode->doc == NULL) return (Qnil); xmlNodeSetBase(xnode, (xmlChar*) StringValuePtr(uri)); return (Qtrue); } /* * call-seq: * node.content -> "string" * * Obtain this node's content as a string. */ static VALUE rxml_node_content_get(VALUE self) { xmlNodePtr xnode; xmlChar *content; VALUE result = Qnil; xnode = rxml_get_xnode(self); content = xmlNodeGetContent(xnode); if (content) { result = rxml_new_cstr(content, NULL); xmlFree(content); } return result; } /* * call-seq: * node.content = "string" * * Set this node's content to the specified string. */ static VALUE rxml_node_content_set(VALUE self, VALUE content) { xmlNodePtr xnode; xmlChar* encoded_content; Check_Type(content, T_STRING); xnode = rxml_get_xnode(self); encoded_content = xmlEncodeSpecialChars(xnode->doc, (xmlChar*) StringValuePtr(content)); xmlNodeSetContent(xnode, encoded_content); xmlFree(encoded_content); return (Qtrue); } /* * call-seq: * node.debug -> true|false * * Print libxml debugging information to stdout. * Requires that libxml was compiled with debugging enabled. */ static VALUE rxml_node_debug(VALUE self) { #ifdef LIBXML_DEBUG_ENABLED xmlNodePtr xnode; xnode = rxml_get_xnode(self); xmlDebugDumpNode(NULL, xnode, 2); return Qtrue; #else rb_warn("libxml was compiled without debugging support."); return Qfalse; #endif } /* * call-seq: * node.first -> XML::Node * * Returns this node's first child node if any. */ static VALUE rxml_node_first_get(VALUE self) { xmlNodePtr xnode; xnode = rxml_get_xnode(self); if (xnode->children) return (rxml_node_wrap(xnode->children)); else return (Qnil); } /* * call-seq: * curr_node << "Some text" * curr_node << node * * Add the specified text or XML::Node as a new child node to the * current node. * * If the specified argument is a string, it should be a raw string * that contains unescaped XML special characters. Entity references * are not supported. * * The method will return the current node. */ static VALUE rxml_node_content_add(VALUE self, VALUE obj) { xmlNodePtr xnode; VALUE str; xnode = rxml_get_xnode(self); /* XXX This should only be legal for a CDATA type node, I think, * resulting in a merge of content, as if a string were passed * danj 070827 */ if (rb_obj_is_kind_of(obj, cXMLNode)) { rxml_node_modify_dom(self, obj, xmlAddChild); } else { str = rb_obj_as_string(obj); if (NIL_P(str) || TYPE(str) != T_STRING) rb_raise(rb_eTypeError, "invalid argument: must be string or XML::Node"); xmlNodeAddContent(xnode, (xmlChar*) StringValuePtr(str)); } return self; } /* * call-seq: * node.doc -> document * * Obtain the XML::Document this node belongs to. */ static VALUE rxml_node_doc(VALUE self) { xmlDocPtr xdoc = NULL; xmlNodePtr xnode = rxml_get_xnode(self); switch (xnode->type) { case XML_DOCUMENT_NODE: #ifdef LIBXML_DOCB_ENABLED case XML_DOCB_DOCUMENT_NODE: #endif case XML_HTML_DOCUMENT_NODE: case XML_NAMESPACE_DECL: break; case XML_ATTRIBUTE_NODE: xdoc = (xmlDocPtr)((xmlAttrPtr) xnode->doc); break; default: xdoc = xnode->doc; } if (xdoc == NULL) return (Qnil); return (VALUE)xdoc->_private; } /* * call-seq: * node.to_s -> "string" * node.to_s(:indent => true, :encoding => 'UTF-8', :level => 0) -> "string" * * Converts a node, and all of its children, to a string representation. * To include only the node's children, use the the XML::Node#inner_xml * method. * * You may provide an optional hash table to control how the string is * generated. Valid options are: * * :indent - Specifies if the string should be indented. The default value * is true. Note that indentation is only added if both :indent is * true and XML.indent_tree_output is true. If :indent is set to false, * then both indentation and line feeds are removed from the result. * * :level - Specifies the indentation level. The amount of indentation * is equal to the (level * number_spaces) + number_spaces, where libxml * defaults the number of spaces to 2. Thus a level of 0 results in * 2 spaces, level 1 results in 4 spaces, level 2 results in 6 spaces, etc. * * :encoding - Specifies the output encoding of the string. It * defaults to XML::Encoding::UTF8. To change it, use one of the * XML::Encoding encoding constants. */ static VALUE rxml_node_to_s(int argc, VALUE *argv, VALUE self) { VALUE result = Qnil; VALUE options = Qnil; xmlNodePtr xnode; xmlCharEncodingHandlerPtr encodingHandler; xmlOutputBufferPtr output; int level = 0; int indent = 1; const xmlChar *xencoding = (const xmlChar*)"UTF-8"; rb_scan_args(argc, argv, "01", &options); if (!NIL_P(options)) { VALUE rencoding, rindent, rlevel; Check_Type(options, T_HASH); rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding"))); rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent"))); rlevel = rb_hash_aref(options, ID2SYM(rb_intern("level"))); if (rindent == Qfalse) indent = 0; if (rlevel != Qnil) level = NUM2INT(rlevel); if (rencoding != Qnil) { xencoding = (const xmlChar*)xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding)); if (!xencoding) rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding)); } } encodingHandler = xmlFindCharEncodingHandler((const char*)xencoding); output = xmlAllocOutputBuffer(encodingHandler); xnode = rxml_get_xnode(self); xmlNodeDumpOutput(output, xnode->doc, xnode, level, indent, (const char*)xencoding); xmlOutputBufferFlush(output); #ifdef LIBXML2_NEW_BUFFER if (output->conv) result = rxml_new_cstr(xmlBufContent(output->conv), xencoding); else result = rxml_new_cstr(xmlBufContent(output->buffer), xencoding); #else if (output->conv) result = rxml_new_cstr(xmlBufferContent(output->conv), xencoding); else result = rxml_new_cstr(xmlBufferContent(output->buffer), xencoding); #endif xmlOutputBufferClose(output); return result; } /* * call-seq: * node.each -> XML::Node * * Iterates over this node's children, including text * nodes, element nodes, etc. If you wish to iterate * only over child elements, use XML::Node#each_element. * * doc = XML::Document.new('model/books.xml') * doc.root.each {|node| puts node} */ static VALUE rxml_node_each(VALUE self) { xmlNodePtr xnode; xmlNodePtr xcurrent; xnode = rxml_get_xnode(self); xcurrent = xnode->children; while (xcurrent) { /* The user could remove this node, so first stache away the next node. */ xmlNodePtr xnext = xcurrent->next; rb_yield(rxml_node_wrap(xcurrent)); xcurrent = xnext; } return Qnil; } /* * call-seq: * node.empty? -> (true|false) * * Determine whether this node is an empty or whitespace only text-node. */ static VALUE rxml_node_empty_q(VALUE self) { xmlNodePtr xnode; xnode = rxml_get_xnode(self); if (xnode == NULL) return (Qnil); return ((xmlIsBlankNode(xnode) == 1) ? Qtrue : Qfalse); } /* * call-seq: * node.eql?(other_node) => (true|false) * * Test equality between the two nodes. Two nodes are equal * if they are the same node.*/ static VALUE rxml_node_eql_q(VALUE self, VALUE other) { if (self == other) { return Qtrue; } else if (NIL_P(other)) { return Qfalse; } else { xmlNodePtr xnode = rxml_get_xnode(self); xmlNodePtr xnode_other = rxml_get_xnode(other); return xnode == xnode_other ? Qtrue : Qfalse; } } /* * call-seq: * node.lang -> "string" * * Obtain the language set for this node, if any. * This is set in XML via the xml:lang attribute. */ static VALUE rxml_node_lang_get(VALUE self) { xmlNodePtr xnode; xmlChar *lang; VALUE result = Qnil; xnode = rxml_get_xnode(self); lang = xmlNodeGetLang(xnode); if (lang) { result = rxml_new_cstr( lang, NULL); xmlFree(lang); } return (result); } // TODO node_lang_set should support setting back to nil /* * call-seq: * node.lang = "string" * * Set the language for this node. This affects the value * of the xml:lang attribute. */ static VALUE rxml_node_lang_set(VALUE self, VALUE lang) { xmlNodePtr xnode; Check_Type(lang, T_STRING); xnode = rxml_get_xnode(self); xmlNodeSetLang(xnode, (xmlChar*) StringValuePtr(lang)); return (Qtrue); } /* * call-seq: * node.last -> XML::Node * * Obtain the last child node of this node, if any. */ static VALUE rxml_node_last_get(VALUE self) { xmlNodePtr xnode; xnode = rxml_get_xnode(self); if (xnode->last) return (rxml_node_wrap(xnode->last)); else return (Qnil); } /* * call-seq: * node.line_num -> num * * Obtain the line number (in the XML document) that this * node was read from. If +default_line_numbers+ is set * false (the default), this method returns zero. */ static VALUE rxml_node_line_num(VALUE self) { xmlNodePtr xnode; long line_num; xnode = rxml_get_xnode(self); if (!xmlLineNumbersDefaultValue) rb_warn( "Line numbers were not retained: use XML::Parser::default_line_numbers=true"); line_num = xmlGetLineNo(xnode); if (line_num == -1) return (Qnil); else return (INT2NUM((long) line_num)); } /* * call-seq: * node.xlink? -> (true|false) * * Determine whether this node is an xlink node. */ static VALUE rxml_node_xlink_q(VALUE self) { xmlNodePtr xnode; xlinkType xlt; xnode = rxml_get_xnode(self); xlt = xlinkIsLink(xnode->doc, xnode); if (xlt == XLINK_TYPE_NONE) return (Qfalse); else return (Qtrue); } /* * call-seq: * node.xlink_type -> num * * Obtain the type identifier for this xlink, if applicable. * If this is not an xlink node (see +xlink?+), will return * nil. */ static VALUE rxml_node_xlink_type(VALUE self) { xmlNodePtr xnode; xlinkType xlt; xnode = rxml_get_xnode(self); xlt = xlinkIsLink(xnode->doc, xnode); if (xlt == XLINK_TYPE_NONE) return (Qnil); else return (INT2NUM(xlt)); } /* * call-seq: * node.xlink_type_name -> "string" * * Obtain the type name for this xlink, if applicable. * If this is not an xlink node (see +xlink?+), will return * nil. */ static VALUE rxml_node_xlink_type_name(VALUE self) { xmlNodePtr xnode; xlinkType xlt; xnode = rxml_get_xnode(self); xlt = xlinkIsLink(xnode->doc, xnode); switch (xlt) { case XLINK_TYPE_NONE: return (Qnil); case XLINK_TYPE_SIMPLE: return (rxml_new_cstr((const xmlChar*)"simple", NULL)); case XLINK_TYPE_EXTENDED: return (rxml_new_cstr((const xmlChar*)"extended", NULL)); case XLINK_TYPE_EXTENDED_SET: return (rxml_new_cstr((const xmlChar*)"extended_set", NULL)); default: rb_fatal("Unknowng xlink type, %d", xlt); } } /* * call-seq: * node.name -> "string" * * Obtain this node's name. */ static VALUE rxml_node_name_get(VALUE self) { xmlNodePtr xnode; const xmlChar *name; xnode = rxml_get_xnode(self); switch (xnode->type) { case XML_DOCUMENT_NODE: #ifdef LIBXML_DOCB_ENABLED case XML_DOCB_DOCUMENT_NODE: #endif case XML_HTML_DOCUMENT_NODE: { xmlDocPtr doc = (xmlDocPtr) xnode; name = doc->URL; break; } case XML_ATTRIBUTE_NODE: { xmlAttrPtr attr = (xmlAttrPtr) xnode; name = attr->name; break; } case XML_NAMESPACE_DECL: { xmlNsPtr ns = (xmlNsPtr) xnode; name = ns->prefix; break; } default: name = xnode->name; break; } if (xnode->name == NULL) return (Qnil); else return (rxml_new_cstr( name, NULL)); } /* * call-seq: * node.name = "string" * * Set this node's name. */ static VALUE rxml_node_name_set(VALUE self, VALUE name) { xmlNodePtr xnode; const xmlChar *xname; Check_Type(name, T_STRING); xnode = rxml_get_xnode(self); xname = (const xmlChar*)StringValuePtr(name); /* Note: calling xmlNodeSetName() for a text node is ignored by libXML. */ xmlNodeSetName(xnode, xname); return (Qtrue); } /* * call-seq: * node.next -> XML::Node * * Returns the next sibling node if one exists. */ static VALUE rxml_node_next_get(VALUE self) { xmlNodePtr xnode; xnode = rxml_get_xnode(self); if (xnode->next) return (rxml_node_wrap(xnode->next)); else return (Qnil); } /* * call-seq: * curr_node.next = node * * Adds the specified node as the next sibling of the current node. * If the node already exists in the document, it is first removed * from its existing context. Any adjacent text nodes will be * merged together, meaning the returned node may be different * than the original node. */ static VALUE rxml_node_next_set(VALUE self, VALUE next) { return rxml_node_modify_dom(self, next, xmlAddNextSibling); } /* * call-seq: * node.parent -> XML::Node * * Obtain this node's parent node, if any. */ static VALUE rxml_node_parent_get(VALUE self) { xmlNodePtr xnode; xnode = rxml_get_xnode(self); if (xnode->parent) return (rxml_node_wrap(xnode->parent)); else return (Qnil); } /* * call-seq: * node.path -> path * * Obtain this node's path. */ static VALUE rxml_node_path(VALUE self) { xmlNodePtr xnode; xmlChar *path; xnode = rxml_get_xnode(self); path = xmlGetNodePath(xnode); if (path == NULL) return (Qnil); else return (rxml_new_cstr( path, NULL)); } /* * call-seq: * node.pointer -> XML::NodeSet * * Evaluates an XPointer expression relative to this node. */ static VALUE rxml_node_pointer(VALUE self, VALUE xptr_str) { return (rxml_xpointer_point2(self, xptr_str)); } /* * call-seq: * node.prev -> XML::Node * * Obtain the previous sibling, if any. */ static VALUE rxml_node_prev_get(VALUE self) { xmlNodePtr xnode; xmlNodePtr node; xnode = rxml_get_xnode(self); switch (xnode->type) { case XML_DOCUMENT_NODE: #ifdef LIBXML_DOCB_ENABLED case XML_DOCB_DOCUMENT_NODE: #endif case XML_HTML_DOCUMENT_NODE: case XML_NAMESPACE_DECL: node = NULL; break; case XML_ATTRIBUTE_NODE: { xmlAttrPtr attr = (xmlAttrPtr) xnode; node = (xmlNodePtr) attr->prev; } break; default: node = xnode->prev; break; } if (node == NULL) return (Qnil); else return (rxml_node_wrap(node)); } /* * call-seq: * curr_node.prev = node * * Adds the specified node as the previous sibling of the current node. * If the node already exists in the document, it is first removed * from its existing context. Any adjacent text nodes will be * merged together, meaning the returned node may be different * than the original node. */ static VALUE rxml_node_prev_set(VALUE self, VALUE prev) { return rxml_node_modify_dom(self, prev, xmlAddPrevSibling); } /* * call-seq: * node.attributes -> attributes * * Returns the XML::Attributes for this node. */ static VALUE rxml_node_attributes_get(VALUE self) { xmlNodePtr xnode; xnode = rxml_get_xnode(self); return rxml_attributes_new(xnode); } /* * call-seq: * node.property("name") -> "string" * node["name"] -> "string" * * Obtain the named property. */ static VALUE rxml_node_attribute_get(VALUE self, VALUE name) { VALUE attributes = rxml_node_attributes_get(self); return rxml_attributes_attribute_get(attributes, name); } /* * call-seq: * node["name"] = "string" * * Set the named property. */ static VALUE rxml_node_property_set(VALUE self, VALUE name, VALUE value) { VALUE attributes = rxml_node_attributes_get(self); return rxml_attributes_attribute_set(attributes, name, value); } /* * call-seq: * node.remove! -> node * * Removes this node and its children from the document tree by setting its document, * parent and siblings to nil. You can add the returned node back into a document. * Otherwise, the node will be freed once any references to it go out of scope. */ static VALUE rxml_node_remove_ex(VALUE self) { xmlNodePtr xnode = rxml_get_xnode(self); // Now unlink the node from its parent xmlUnlinkNode(xnode); // Ruby now manages this node rxml_node_manage(xnode, self); // Now return the removed node so the user can do something with it return self; } /* * call-seq: * curr_node.sibling = node * * Adds the specified node as the end of the current node's list * of siblings. If the node already exists in the document, it * is first removed from its existing context. Any adjacent text * nodes will be merged together, meaning the returned node may * be different than the original node. */ static VALUE rxml_node_sibling_set(VALUE self, VALUE sibling) { return rxml_node_modify_dom(self, sibling, xmlAddSibling); } /* * call-seq: * text_node.output_escaping? -> (true|false) * element_node.output_escaping? -> (true|false|nil) * attribute_node.output_escaping? -> (true|false|nil) * other_node.output_escaping? -> (nil) * * Determine whether this node escapes it's output or not. * * Text nodes return only +true+ or +false+. Element and attribute nodes * examine their immediate text node children to determine the value. * Any other type of node always returns +nil+. * * If an element or attribute node has at least one immediate child text node * and all the immediate text node children have the same +output_escaping?+ * value, that value is returned. Otherwise, +nil+ is returned. */ static VALUE rxml_node_output_escaping_q(VALUE self) { xmlNodePtr xnode; xnode = rxml_get_xnode(self); switch (xnode->type) { case XML_TEXT_NODE: return xnode->name==xmlStringTextNoenc ? Qfalse : Qtrue; case XML_ELEMENT_NODE: case XML_ATTRIBUTE_NODE: { xmlNodePtr tmp = xnode->children; const xmlChar *match = NULL; /* Find the first text node and use it as the reference. */ while (tmp && tmp->type != XML_TEXT_NODE) tmp = tmp->next; if (! tmp) return Qnil; match = tmp->name; /* Walk the remaining text nodes until we run out or one doesn't match. */ while (tmp && (tmp->type != XML_TEXT_NODE || match == tmp->name)) tmp = tmp->next; /* We're left with either the mismatched node or the aggregate result. */ return tmp ? Qnil : (match==xmlStringTextNoenc ? Qfalse : Qtrue); } break; default: return Qnil; } } /* * call-seq: * text_node.output_escaping = true|false * element_node.output_escaping = true|false * attribute_node.output_escaping = true|false * * Controls whether this text node or the immediate text node children of an * element or attribute node escapes their output. Any other type of node * will simply ignore this operation. * * Text nodes which are added to an element or attribute node will be affected * by any previous setting of this property. */ static VALUE rxml_node_output_escaping_set(VALUE self, VALUE value) { xmlNodePtr xnode; xnode = rxml_get_xnode(self); switch (xnode->type) { case XML_TEXT_NODE: xnode->name = (value != Qfalse && value != Qnil) ? xmlStringText : xmlStringTextNoenc; break; case XML_ELEMENT_NODE: case XML_ATTRIBUTE_NODE: { const xmlChar *name = (value != Qfalse && value != Qnil) ? xmlStringText : xmlStringTextNoenc; xmlNodePtr tmp; for (tmp = xnode->children; tmp; tmp = tmp->next) if (tmp->type == XML_TEXT_NODE) tmp->name = name; } break; default: return Qnil; } return (value!=Qfalse && value!=Qnil) ? Qtrue : Qfalse; } /* * call-seq: * node.space_preserve -> (true|false) * * Determine whether this node preserves whitespace. */ static VALUE rxml_node_space_preserve_get(VALUE self) { xmlNodePtr xnode; xnode = rxml_get_xnode(self); return (INT2NUM(xmlNodeGetSpacePreserve(xnode))); } /* * call-seq: * node.space_preserve = true|false * * Control whether this node preserves whitespace. */ static VALUE rxml_node_space_preserve_set(VALUE self, VALUE value) { xmlNodePtr xnode; xnode = rxml_get_xnode(self); if (value == Qfalse) xmlNodeSetSpacePreserve(xnode, 0); else xmlNodeSetSpacePreserve(xnode, 1); return (Qnil); } /* * call-seq: * node.type -> num * * Obtain this node's type identifier. */ static VALUE rxml_node_type(VALUE self) { xmlNodePtr xnode; xnode = rxml_get_xnode(self); return (INT2NUM(xnode->type)); } /* * call-seq: * node.copy -> XML::Node * * Creates a copy of this node. To create a * shallow copy set the deep parameter to false. * To create a deep copy set the deep parameter * to true. * */ static VALUE rxml_node_copy(VALUE self, VALUE deep) { xmlNodePtr xnode; xmlNodePtr xcopy; int recursive = (deep == Qnil || deep == Qfalse) ? 0 : 1; xnode = rxml_get_xnode(self); xcopy = xmlCopyNode(xnode, recursive); if (xcopy) return rxml_node_wrap(xcopy); else return Qnil; } void rxml_init_node(void) { cXMLNode = rb_define_class_under(mXML, "Node", rb_cObject); rb_define_const(cXMLNode, "SPACE_DEFAULT", INT2NUM(0)); rb_define_const(cXMLNode, "SPACE_PRESERVE", INT2NUM(1)); rb_define_const(cXMLNode, "SPACE_NOT_INHERIT", INT2NUM(-1)); rb_define_const(cXMLNode, "XLINK_ACTUATE_AUTO", INT2NUM(1)); rb_define_const(cXMLNode, "XLINK_ACTUATE_NONE", INT2NUM(0)); rb_define_const(cXMLNode, "XLINK_ACTUATE_ONREQUEST", INT2NUM(2)); rb_define_const(cXMLNode, "XLINK_SHOW_EMBED", INT2NUM(2)); rb_define_const(cXMLNode, "XLINK_SHOW_NEW", INT2NUM(1)); rb_define_const(cXMLNode, "XLINK_SHOW_NONE", INT2NUM(0)); rb_define_const(cXMLNode, "XLINK_SHOW_REPLACE", INT2NUM(3)); rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED", INT2NUM(2)); rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED_SET", INT2NUM(3)); rb_define_const(cXMLNode, "XLINK_TYPE_NONE", INT2NUM(0)); rb_define_const(cXMLNode, "XLINK_TYPE_SIMPLE", INT2NUM(1)); rb_define_const(cXMLNode, "ELEMENT_NODE", INT2FIX(XML_ELEMENT_NODE)); rb_define_const(cXMLNode, "ATTRIBUTE_NODE", INT2FIX(XML_ATTRIBUTE_NODE)); rb_define_const(cXMLNode, "TEXT_NODE", INT2FIX(XML_TEXT_NODE)); rb_define_const(cXMLNode, "CDATA_SECTION_NODE", INT2FIX(XML_CDATA_SECTION_NODE)); rb_define_const(cXMLNode, "ENTITY_REF_NODE", INT2FIX(XML_ENTITY_REF_NODE)); rb_define_const(cXMLNode, "ENTITY_NODE", INT2FIX(XML_ENTITY_NODE)); rb_define_const(cXMLNode, "PI_NODE", INT2FIX(XML_PI_NODE)); rb_define_const(cXMLNode, "COMMENT_NODE", INT2FIX(XML_COMMENT_NODE)); rb_define_const(cXMLNode, "DOCUMENT_NODE", INT2FIX(XML_DOCUMENT_NODE)); rb_define_const(cXMLNode, "DOCUMENT_TYPE_NODE", INT2FIX(XML_DOCUMENT_TYPE_NODE)); rb_define_const(cXMLNode, "DOCUMENT_FRAG_NODE", INT2FIX(XML_DOCUMENT_FRAG_NODE)); rb_define_const(cXMLNode, "NOTATION_NODE", INT2FIX(XML_NOTATION_NODE)); rb_define_const(cXMLNode, "HTML_DOCUMENT_NODE", INT2FIX(XML_HTML_DOCUMENT_NODE)); rb_define_const(cXMLNode, "DTD_NODE", INT2FIX(XML_DTD_NODE)); rb_define_const(cXMLNode, "ELEMENT_DECL", INT2FIX(XML_ELEMENT_DECL)); rb_define_const(cXMLNode, "ATTRIBUTE_DECL", INT2FIX(XML_ATTRIBUTE_DECL)); rb_define_const(cXMLNode, "ENTITY_DECL", INT2FIX(XML_ENTITY_DECL)); rb_define_const(cXMLNode, "NAMESPACE_DECL", INT2FIX(XML_NAMESPACE_DECL)); rb_define_const(cXMLNode, "XINCLUDE_START", INT2FIX(XML_XINCLUDE_START)); rb_define_const(cXMLNode, "XINCLUDE_END", INT2FIX(XML_XINCLUDE_END)); #ifdef LIBXML_DOCB_ENABLED rb_define_const(cXMLNode, "DOCB_DOCUMENT_NODE", INT2FIX(XML_DOCB_DOCUMENT_NODE)); #else rb_define_const(cXMLNode, "DOCB_DOCUMENT_NODE", Qnil); #endif rb_define_singleton_method(cXMLNode, "new_cdata", rxml_node_new_cdata, -1); rb_define_singleton_method(cXMLNode, "new_comment", rxml_node_new_comment, -1); rb_define_singleton_method(cXMLNode, "new_pi", rxml_node_new_pi, -1); rb_define_singleton_method(cXMLNode, "new_text", rxml_node_new_text, 1); /* Initialization */ rb_define_alloc_func(cXMLNode, rxml_node_alloc); rb_define_method(cXMLNode, "initialize", rxml_node_initialize, -1); /* Traversal */ rb_include_module(cXMLNode, rb_mEnumerable); rb_define_method(cXMLNode, "[]", rxml_node_attribute_get, 1); rb_define_method(cXMLNode, "each", rxml_node_each, 0); rb_define_method(cXMLNode, "first", rxml_node_first_get, 0); rb_define_method(cXMLNode, "last", rxml_node_last_get, 0); rb_define_method(cXMLNode, "next", rxml_node_next_get, 0); rb_define_method(cXMLNode, "parent", rxml_node_parent_get, 0); rb_define_method(cXMLNode, "prev", rxml_node_prev_get, 0); /* Modification */ rb_define_method(cXMLNode, "[]=", rxml_node_property_set, 2); rb_define_method(cXMLNode, "<<", rxml_node_content_add, 1); rb_define_method(cXMLNode, "sibling=", rxml_node_sibling_set, 1); rb_define_method(cXMLNode, "next=", rxml_node_next_set, 1); rb_define_method(cXMLNode, "prev=", rxml_node_prev_set, 1); /* Rest of the node api */ rb_define_method(cXMLNode, "attributes", rxml_node_attributes_get, 0); rb_define_method(cXMLNode, "base_uri", rxml_node_base_uri_get, 0); rb_define_method(cXMLNode, "base_uri=", rxml_node_base_uri_set, 1); rb_define_method(cXMLNode, "blank?", rxml_node_empty_q, 0); rb_define_method(cXMLNode, "copy", rxml_node_copy, 1); rb_define_method(cXMLNode, "content", rxml_node_content_get, 0); rb_define_method(cXMLNode, "content=", rxml_node_content_set, 1); rb_define_method(cXMLNode, "debug", rxml_node_debug, 0); rb_define_method(cXMLNode, "doc", rxml_node_doc, 0); rb_define_method(cXMLNode, "empty?", rxml_node_empty_q, 0); rb_define_method(cXMLNode, "eql?", rxml_node_eql_q, 1); rb_define_method(cXMLNode, "lang", rxml_node_lang_get, 0); rb_define_method(cXMLNode, "lang=", rxml_node_lang_set, 1); rb_define_method(cXMLNode, "line_num", rxml_node_line_num, 0); rb_define_method(cXMLNode, "name", rxml_node_name_get, 0); rb_define_method(cXMLNode, "name=", rxml_node_name_set, 1); rb_define_method(cXMLNode, "node_type", rxml_node_type, 0); rb_define_method(cXMLNode, "output_escaping?", rxml_node_output_escaping_q, 0); rb_define_method(cXMLNode, "output_escaping=", rxml_node_output_escaping_set, 1); rb_define_method(cXMLNode, "path", rxml_node_path, 0); rb_define_method(cXMLNode, "pointer", rxml_node_pointer, 1); rb_define_method(cXMLNode, "remove!", rxml_node_remove_ex, 0); rb_define_method(cXMLNode, "space_preserve", rxml_node_space_preserve_get, 0); rb_define_method(cXMLNode, "space_preserve=", rxml_node_space_preserve_set, 1); rb_define_method(cXMLNode, "to_s", rxml_node_to_s, -1); rb_define_method(cXMLNode, "xlink?", rxml_node_xlink_q, 0); rb_define_method(cXMLNode, "xlink_type", rxml_node_xlink_type, 0); rb_define_method(cXMLNode, "xlink_type_name", rxml_node_xlink_type_name, 0); rb_define_alias(cXMLNode, "==", "eql?"); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_document.c0000644000004100000410000007052113760147770022026 0ustar www-datawww-data/* * Document-class: LibXML::XML::Document * * The XML::Document class provides a tree based API for working * with xml documents. You may directly create a document and * manipulate it, or create a document from a data source by * using an XML::Parser object. * * To read a document from a file: * * doc = XML::Document.file('my_file') * * To use a parser to read a document: * * parser = XML::Parser.file('my_file') * doc = parser.parse * * To create a document from scratch: * * doc = XML::Document.new() * doc.root = XML::Node.new('root_node') * doc.root << XML::Node.new('elem1') * doc.save(filename, :indent => true, :encoding => XML::Encoding::UTF_8) * * To write a document to a file: * * doc = XML::Document.new() * doc.root = XML::Node.new('root_node') * root = doc.root * * root << elem1 = XML::Node.new('elem1') * elem1['attr1'] = 'val1' * elem1['attr2'] = 'val2' * * root << elem2 = XML::Node.new('elem2') * elem2['attr1'] = 'val1' * elem2['attr2'] = 'val2' * * root << elem3 = XML::Node.new('elem3') * elem3 << elem4 = XML::Node.new('elem4') * elem3 << elem5 = XML::Node.new('elem5') * * elem5 << elem6 = XML::Node.new('elem6') * elem6 << 'Content for element 6' * * elem3['attr'] = 'baz' * * doc.save(filename, :indent => true, :encoding => XML::Encoding::UTF_8) */ #include #include "ruby_libxml.h" #include "ruby_xml_document.h" VALUE cXMLDocument; void rxml_document_free(xmlDocPtr xdoc) { xdoc->_private = NULL; xmlFreeDoc(xdoc); } VALUE rxml_document_wrap(xmlDocPtr xdoc) { VALUE result = Qnil; // Is this node is already wrapped? if (xdoc->_private != NULL) { result = (VALUE)xdoc->_private; } else { result = Data_Wrap_Struct(cXMLDocument, NULL, rxml_document_free, xdoc); xdoc->_private = (void*)result; } return result; } /* * call-seq: * XML::Document.alloc(xml_version = 1.0) -> document * * Alocates a new XML::Document, optionally specifying the * XML version. */ static VALUE rxml_document_alloc(VALUE klass) { return Data_Wrap_Struct(klass, NULL, rxml_document_free, NULL); } /* * call-seq: * XML::Document.initialize(xml_version = 1.0) -> document * * Initializes a new XML::Document, optionally specifying the * XML version. */ static VALUE rxml_document_initialize(int argc, VALUE *argv, VALUE self) { xmlDocPtr xdoc; VALUE xmlver; switch (argc) { case 0: xmlver = rb_str_new2("1.0"); break; case 1: rb_scan_args(argc, argv, "01", &xmlver); break; default: rb_raise(rb_eArgError, "wrong number of arguments (need 0 or 1)"); } Check_Type(xmlver, T_STRING); xdoc = xmlNewDoc((xmlChar*) StringValuePtr(xmlver)); // Link the ruby object to the document and the document to the ruby object RDATA(self)->data = xdoc; xdoc->_private = (void*)self; return self; } /* XML_C14N_1* constants are not defined until libxml 1.1.25, so if they are not defined then define these constants to map to zero, the same value as XML_C14N_1_0. */ /* XML_C14N* constants are not defined until libxml 1.1.25, so define them if needed so things compile. */ #ifndef XML_C14N_1_0 #define XML_C14N_1_0 0 #define XML_C14N_EXCLUSIVE_1_0 XML_C14N_1_0 #define XML_C14N_1_1 XML_C14N_1_0 #endif /* * :call-seq: * document.canonicalize -> String * document.canonicalize(options) -> String * * Returns a string containing the canonicalized form of the document. * Implemented to include all of the functionality of the libxml2 * {xmlC14NDocDumpMemory}[http://xmlsoft.org/html/libxml-c14n.html#xmlC14NDocDumpMemory] * method. * * === Options * [comments] * * *Type:* Boolean * * *Default:* false * Specifies if comments should be output. * * Must be boolean, otherwise defaults to false. * [inclusive_ns_prefixes] * * *Type:* Array of strings * * *Default:* empty array * Array of namespace prefixes to include in exclusive canonicalization only. * * The last item in the list is reserved for a NULL value because the C method demands it, therefore * up to the first 255 valid entries will be used. * * Only used for *XML_C14N_EXCLUSIVE_1_0* mode. Ignored otherwise. * [mode] * * *Type:* XML::Document Constant * * *Default:* XML_C14N_1_0 * Specifies the mode of canonicalization. * * *NOTE:* XML_C14N_1_1 may not be fully implemented upon compilation due to C library compatibility. * Please check if XML_C14N_1_0 and XML_C14N_1_1 are the same value prior to using XML_C14N_1_1. * [nodes] * * *Type:* Array of XML::Node objects * * *Default:* empty array * XML::Nodes to include in the canonicalization process * * For large lists of more than 256 valid namespaces, up to the first 256 valid entries will be used. */ #define C14N_NS_LIMIT 256 #define C14N_NODESET_LIMIT 256 static VALUE rxml_document_canonicalize(int argc, VALUE *argv, VALUE self) { VALUE result = Qnil; xmlDocPtr xdoc; xmlChar *buffer = NULL; VALUE option_hash = Qnil; VALUE o_nodes = Qnil; // :comments option int comments = 0; // :mode option int c14n_mode = XML_C14N_1_0; // :inclusive_ns_prefixes option (ARRAY) xmlChar * inc_ns_prefixes_ptr[C14N_NS_LIMIT]; // :nodes option (ARRAY) xmlNodePtr node_ptr_array[C14N_NODESET_LIMIT]; xmlNodeSet nodeset = { 0, C14N_NODESET_LIMIT, NULL }; /* At least one NULL value must be defined in the array or the extension will * segfault when using XML_C14N_EXCLUSIVE_1_0 mode. * API docs: "list of inclusive namespace prefixes ended with a NULL" */ inc_ns_prefixes_ptr[0] = NULL; rb_scan_args(argc, argv, "01", &option_hash); // Do stuff if ruby hash passed as argument if (!NIL_P(option_hash)) { VALUE o_comments = Qnil; VALUE o_mode = Qnil; VALUE o_i_ns_prefixes = Qnil; Check_Type(option_hash, T_HASH); o_comments = rb_hash_aref(option_hash, ID2SYM(rb_intern("comments"))); comments = (RTEST(o_comments) ? 1 : 0); o_mode = rb_hash_aref(option_hash, ID2SYM(rb_intern("mode"))); if (!NIL_P(o_mode)) { Check_Type(o_mode, T_FIXNUM); c14n_mode = NUM2INT(o_mode); //TODO: clean this up //if (c14n_mode > 2) { c14n_mode = 0; } //mode_int = (NUM2INT(o_mode) > 2 ? 0 : NUM2INT(o_mode)); } o_i_ns_prefixes = rb_hash_aref(option_hash, ID2SYM(rb_intern("inclusive_ns_prefixes"))); if (!NIL_P(o_i_ns_prefixes)) { int i; int p = 0; //pointer array index VALUE *list_in = NULL; long list_size = 0; Check_Type(o_i_ns_prefixes, T_ARRAY); list_in = RARRAY_PTR(o_i_ns_prefixes); list_size = RARRAY_LEN(o_i_ns_prefixes); if (list_size > 0) { for(i=0; i < list_size; ++i) { if (p >= C14N_NS_LIMIT) { break; } if (RTEST(list_in[i])) { if (TYPE(list_in[i]) == T_STRING) { inc_ns_prefixes_ptr[p] = (xmlChar *)StringValueCStr(list_in[i]); p++; } } } } // ensure p is not out of bound p = (p >= C14N_NS_LIMIT ? (C14N_NS_LIMIT-1) : p); // API docs: "list of inclusive namespace prefixes ended with a NULL" // Set last element to NULL inc_ns_prefixes_ptr[p] = NULL; } //o_ns_prefixes will free at end of block o_nodes = rb_hash_aref(option_hash, ID2SYM(rb_intern("nodes"))); if (!NIL_P(o_nodes)) { int i; int p = 0; // index of pointer array VALUE * list_in = NULL; long node_list_size = 0; if (CLASS_OF(o_nodes) == cXMLXPathObject) { o_nodes = rb_funcall(o_nodes, rb_intern("to_a"), 0); } else { Check_Type(o_nodes, T_ARRAY); } list_in = RARRAY_PTR(o_nodes); node_list_size = RARRAY_LEN(o_nodes); for (i=0; i < node_list_size; ++i) { if (p >= C14N_NODESET_LIMIT) { break; } if (RTEST(list_in[i])) { xmlNodePtr node_ptr; Data_Get_Struct(list_in[i], xmlNode, node_ptr); node_ptr_array[p] = node_ptr; p++; } } // Need to set values in nodeset struct nodeset.nodeNr = (node_list_size > C14N_NODESET_LIMIT ? C14N_NODESET_LIMIT : (int)node_list_size); nodeset.nodeTab = node_ptr_array; } }//option_hash Data_Get_Struct(self, xmlDoc, xdoc); xmlC14NDocDumpMemory(xdoc, (nodeset.nodeNr == 0 ? NULL : &nodeset), c14n_mode, inc_ns_prefixes_ptr, comments, &buffer); if (buffer) { result = rxml_new_cstr( buffer, NULL); xmlFree(buffer); } return result; } /* * call-seq: * document.compression -> num * * Obtain this document's compression mode identifier. */ static VALUE rxml_document_compression_get(VALUE self) { #ifdef HAVE_ZLIB_H xmlDocPtr xdoc; int compmode; Data_Get_Struct(self, xmlDoc, xdoc); compmode = xmlGetDocCompressMode(xdoc); if (compmode == -1) return(Qnil); else return(INT2NUM(compmode)); #else rb_warn("libxml not compiled with zlib support"); return (Qfalse); #endif } /* * call-seq: * document.compression = num * * Set this document's compression mode. */ static VALUE rxml_document_compression_set(VALUE self, VALUE num) { #ifdef HAVE_ZLIB_H xmlDocPtr xdoc; int compmode; Check_Type(num, T_FIXNUM); Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc == NULL) { return(Qnil); } else { xmlSetDocCompressMode(xdoc, NUM2INT(num)); compmode = xmlGetDocCompressMode(xdoc); if (compmode == -1) return(Qnil); else return(INT2NUM(compmode)); } #else rb_warn("libxml compiled without zlib support"); return (Qfalse); #endif } /* * call-seq: * document.compression? -> (true|false) * * Determine whether this document is compressed. */ static VALUE rxml_document_compression_q(VALUE self) { #ifdef HAVE_ZLIB_H xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->compression != -1) return(Qtrue); else return(Qfalse); #else rb_warn("libxml compiled without zlib support"); return (Qfalse); #endif } /* * call-seq: * document.child -> node * * Get this document's child node. */ static VALUE rxml_document_child_get(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->children == NULL) return (Qnil); return rxml_node_wrap(xdoc->children); } /* * call-seq: * document.child? -> (true|false) * * Determine whether this document has a child node. */ static VALUE rxml_document_child_q(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->children == NULL) return (Qfalse); else return (Qtrue); } /* * call-seq: * node.debug -> true|false * * Print libxml debugging information to stdout. * Requires that libxml was compiled with debugging enabled. */ static VALUE rxml_document_debug(VALUE self) { #ifdef LIBXML_DEBUG_ENABLED xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); xmlDebugDumpDocument(NULL, xdoc); return Qtrue; #else rb_warn("libxml was compiled without debugging support."); return Qfalse; #endif } /* * call-seq: * document.encoding -> XML::Encoding::UTF_8 * * Returns the LibXML encoding constant specified by this document. */ static VALUE rxml_document_encoding_get(VALUE self) { xmlDocPtr xdoc; const char *xencoding; Data_Get_Struct(self, xmlDoc, xdoc); xencoding = (const char*)xdoc->encoding; return INT2NUM(xmlParseCharEncoding(xencoding)); } /* * call-seq: * document.rb_encoding -> Encoding * * Returns the Ruby encoding specified by this document * (available on Ruby 1.9.x and higher). */ static VALUE rxml_document_rb_encoding_get(VALUE self) { xmlDocPtr xdoc; rb_encoding* rbencoding; Data_Get_Struct(self, xmlDoc, xdoc); rbencoding = rxml_xml_encoding_to_rb_encoding(mXMLEncoding, xmlParseCharEncoding((const char*)xdoc->encoding)); return rb_enc_from_encoding(rbencoding); } /* * call-seq: * document.encoding = XML::Encoding::UTF_8 * * Set the encoding for this document. */ static VALUE rxml_document_encoding_set(VALUE self, VALUE encoding) { xmlDocPtr xdoc; const char* xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(encoding)); Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->encoding != NULL) xmlFree((xmlChar *) xdoc->encoding); xdoc->encoding = xmlStrdup((xmlChar *)xencoding); return self; } /* * call-seq: * document.import(node) -> XML::Node * * Creates a copy of the node that can be inserted into the * current document. * * IMPORTANT - The returned node MUST be inserted into the document. * This is because the returned node refereces internal LibXML data * structures owned by the document. Therefore, if the document is * is freed before the the node is freed a segmentation fault will occur. */ static VALUE rxml_document_import(VALUE self, VALUE node) { xmlDocPtr xdoc; xmlNodePtr xnode, xresult; Data_Get_Struct(self, xmlDoc, xdoc); Data_Get_Struct(node, xmlNode, xnode); xresult = xmlDocCopyNode(xnode, xdoc, 1); if (xresult == NULL) rxml_raise(&xmlLastError); return rxml_node_wrap(xresult); } /* * call-seq: * document.last -> node * * Obtain the last node. */ static VALUE rxml_document_last_get(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->last == NULL) return (Qnil); return rxml_node_wrap(xdoc->last); } /* * call-seq: * document.last? -> (true|false) * * Determine whether there is a last node. */ static VALUE rxml_document_last_q(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->last == NULL) return (Qfalse); else return (Qtrue); } /* * call-seq: * document.next -> node * * Obtain the next node. */ static VALUE rxml_document_next_get(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->next == NULL) return (Qnil); return rxml_node_wrap(xdoc->next); } /* * call-seq: * document.next? -> (true|false) * * Determine whether there is a next node. */ static VALUE rxml_document_next_q(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->next == NULL) return (Qfalse); else return (Qtrue); } /* * call-seq: * node.type -> num * * Obtain this node's type identifier. */ static VALUE rxml_document_node_type(VALUE self) { xmlNodePtr xnode; Data_Get_Struct(self, xmlNode, xnode); return (INT2NUM(xnode->type)); } /* * call-seq: * document.parent -> node * * Obtain the parent node. */ static VALUE rxml_document_parent_get(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->parent == NULL) return (Qnil); return rxml_node_wrap(xdoc->parent); } /* * call-seq: * document.parent? -> (true|false) * * Determine whether there is a parent node. */ static VALUE rxml_document_parent_q(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->parent == NULL) return (Qfalse); else return (Qtrue); } /* * call-seq: * document.prev -> node * * Obtain the previous node. */ static VALUE rxml_document_prev_get(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->prev == NULL) return (Qnil); return rxml_node_wrap(xdoc->prev); } /* * call-seq: * document.prev? -> (true|false) * * Determine whether there is a previous node. */ static VALUE rxml_document_prev_q(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->prev == NULL) return (Qfalse); else return (Qtrue); } /* * call-seq: * document.root -> node * * Obtain the root node. */ static VALUE rxml_document_root_get(VALUE self) { xmlDocPtr xdoc; xmlNodePtr root; Data_Get_Struct(self, xmlDoc, xdoc); root = xmlDocGetRootElement(xdoc); if (root == NULL) return (Qnil); return rxml_node_wrap(root); } /* * call-seq: * document.root = node * * Set the root node. */ static VALUE rxml_document_root_set(VALUE self, VALUE node) { xmlDocPtr xdoc; xmlNodePtr xnode; if (rb_obj_is_kind_of(node, cXMLNode) == Qfalse) rb_raise(rb_eTypeError, "must pass an XML::Node type object"); Data_Get_Struct(self, xmlDoc, xdoc); Data_Get_Struct(node, xmlNode, xnode); if (xnode->doc != NULL && xnode->doc != xdoc) rb_raise(eXMLError, "Nodes belong to different documents. You must first import the node by calling LibXML::XML::Document.import"); xmlDocSetRootElement(xdoc, xnode); // Ruby no longer manages this nodes memory rxml_node_unmanage(xnode, node); return node; } /* * call-seq: * document.save(filename) -> int * document.save(filename, :indent => true, :encoding => XML::Encoding::UTF_8) -> int * * Saves a document to a file. You may provide an optional hash table * to control how the string is generated. Valid options are: * * :indent - Specifies if the string should be indented. The default value * is true. Note that indentation is only added if both :indent is * true and XML.indent_tree_output is true. If :indent is set to false, * then both indentation and line feeds are removed from the result. * * :encoding - Specifies the output encoding of the string. It * defaults to the original encoding of the document (see * #encoding. To override the orginal encoding, use one of the * XML::Encoding encoding constants. */ static VALUE rxml_document_save(int argc, VALUE *argv, VALUE self) { VALUE options = Qnil; VALUE filename = Qnil; xmlDocPtr xdoc; int indent = 1; const char *xfilename; const xmlChar *xencoding; int length; rb_scan_args(argc, argv, "11", &filename, &options); Check_Type(filename, T_STRING); xfilename = StringValuePtr(filename); Data_Get_Struct(self, xmlDoc, xdoc); xencoding = xdoc->encoding; if (!NIL_P(options)) { VALUE rencoding, rindent; Check_Type(options, T_HASH); rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding"))); rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent"))); if (rindent == Qfalse) indent = 0; if (rencoding != Qnil) { xencoding = (const xmlChar*)xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding)); if (!xencoding) rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding)); } } length = xmlSaveFormatFileEnc(xfilename, xdoc, (const char*)xencoding, indent); if (length == -1) rxml_raise(&xmlLastError); return (INT2NUM(length)); } /* * call-seq: * document.standalone? -> (true|false) * * Determine whether this is a standalone document. */ static VALUE rxml_document_standalone_q(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->standalone) return (Qtrue); else return (Qfalse); } /* * call-seq: * document.to_s -> "string" * document.to_s(:indent => true, :encoding => XML::Encoding::UTF_8) -> "string" * * Converts a document, and all of its children, to a string representation. * You may provide an optional hash table to control how the string is * generated. Valid options are: * * :indent - Specifies if the string should be indented. The default value * is true. Note that indentation is only added if both :indent is * true and XML.indent_tree_output is true. If :indent is set to false, * then both indentation and line feeds are removed from the result. * * :encoding - Specifies the output encoding of the string. It * defaults to XML::Encoding::UTF8. To change it, use one of the * XML::Encoding encoding constants. */ static VALUE rxml_document_to_s(int argc, VALUE *argv, VALUE self) { VALUE result; VALUE options = Qnil; xmlDocPtr xdoc; int indent = 1; const xmlChar *xencoding = (const xmlChar*) "UTF-8"; xmlChar *buffer; int length; rb_scan_args(argc, argv, "01", &options); if (!NIL_P(options)) { VALUE rencoding, rindent; Check_Type(options, T_HASH); rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding"))); rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent"))); if (rindent == Qfalse) indent = 0; if (rencoding != Qnil) { xencoding = (const xmlChar*)xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding)); if (!xencoding) rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding)); } } Data_Get_Struct(self, xmlDoc, xdoc); xmlDocDumpFormatMemoryEnc(xdoc, &buffer, &length, (const char*)xencoding, indent); result = rxml_new_cstr(buffer, xencoding); xmlFree(buffer); return result; } /* * call-seq: * document.url -> "url" * * Obtain this document's source URL, if any. */ static VALUE rxml_document_url_get(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->URL == NULL) return (Qnil); else return (rxml_new_cstr( xdoc->URL, NULL)); } /* * call-seq: * document.version -> "version" * * Obtain the XML version specified by this document. */ static VALUE rxml_document_version_get(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); if (xdoc->version == NULL) return (Qnil); else return (rxml_new_cstr( xdoc->version, NULL)); } /* * call-seq: * document.xhtml? -> (true|false) * * Determine whether this is an XHTML document. */ static VALUE rxml_document_xhtml_q(VALUE self) { xmlDocPtr xdoc; xmlDtdPtr xdtd; Data_Get_Struct(self, xmlDoc, xdoc); xdtd = xmlGetIntSubset(xdoc); if (xdtd != NULL && xmlIsXHTML(xdtd->SystemID, xdtd->ExternalID) > 0) return (Qtrue); else return (Qfalse); } /* * call-seq: * document.xinclude -> num * * Process xinclude directives in this document. */ static VALUE rxml_document_xinclude(VALUE self) { #ifdef LIBXML_XINCLUDE_ENABLED xmlDocPtr xdoc; int ret; Data_Get_Struct(self, xmlDoc, xdoc); ret = xmlXIncludeProcess(xdoc); if (ret >= 0) { return(INT2NUM(ret)); } else { rxml_raise(&xmlLastError); return Qnil; } #else rb_warn( "libxml was compiled without XInclude support. Please recompile libxml and ruby-libxml"); return (Qfalse); #endif } /* * call-seq: * document.order_elements! * * Call this routine to speed up XPath computation on static documents. * This stamps all the element nodes with the document order. */ static VALUE rxml_document_order_elements(VALUE self) { xmlDocPtr xdoc; Data_Get_Struct(self, xmlDoc, xdoc); return LONG2FIX(xmlXPathOrderDocElems(xdoc)); } /* * call-seq: * document.validate_schema(schema) * * Validate this document against the specified XML::Schema. * If the document is valid the method returns true. Otherwise an * exception is raised with validation information. */ static VALUE rxml_document_validate_schema(VALUE self, VALUE schema) { xmlSchemaValidCtxtPtr vptr; xmlDocPtr xdoc; xmlSchemaPtr xschema; int is_invalid; Data_Get_Struct(self, xmlDoc, xdoc); Data_Get_Struct(schema, xmlSchema, xschema); vptr = xmlSchemaNewValidCtxt(xschema); is_invalid = xmlSchemaValidateDoc(vptr, xdoc); xmlSchemaFreeValidCtxt(vptr); if (is_invalid) { rxml_raise(&xmlLastError); return Qfalse; } else { return Qtrue; } } /* * call-seq: * document.validate_relaxng(relaxng) * * Validate this document against the specified XML::RelaxNG. * If the document is valid the method returns true. Otherwise an * exception is raised with validation information. */ static VALUE rxml_document_validate_relaxng(VALUE self, VALUE relaxng) { xmlRelaxNGValidCtxtPtr vptr; xmlDocPtr xdoc; xmlRelaxNGPtr xrelaxng; int is_invalid; Data_Get_Struct(self, xmlDoc, xdoc); Data_Get_Struct(relaxng, xmlRelaxNG, xrelaxng); vptr = xmlRelaxNGNewValidCtxt(xrelaxng); is_invalid = xmlRelaxNGValidateDoc(vptr, xdoc); xmlRelaxNGFreeValidCtxt(vptr); if (is_invalid) { rxml_raise(&xmlLastError); return Qfalse; } else { return Qtrue; } } /* * call-seq: * document.validate(dtd) -> (true|false) * * Validate this document against the specified XML::DTD. * If the document is valid the method returns true. Otherwise an * exception is raised with validation information. */ static VALUE rxml_document_validate_dtd(VALUE self, VALUE dtd) { xmlValidCtxt ctxt; xmlDocPtr xdoc; xmlDtdPtr xdtd; Data_Get_Struct(self, xmlDoc, xdoc); Data_Get_Struct(dtd, xmlDtd, xdtd); /* Setup context */ memset(&ctxt, 0, sizeof(xmlValidCtxt)); if (xmlValidateDtd(&ctxt, xdoc, xdtd)) { return Qtrue; } else { rxml_raise(&xmlLastError); return Qfalse; } } void rxml_init_document(void) { cXMLDocument = rb_define_class_under(mXML, "Document", rb_cObject); rb_define_alloc_func(cXMLDocument, rxml_document_alloc); /* Original C14N 1.0 spec */ rb_define_const(cXMLDocument, "XML_C14N_1_0", INT2NUM(XML_C14N_1_0)); /* Exclusive C14N 1.0 spec */ rb_define_const(cXMLDocument, "XML_C14N_EXCLUSIVE_1_0", INT2NUM(XML_C14N_EXCLUSIVE_1_0)); /* C14N 1.1 spec */ rb_define_const(cXMLDocument, "XML_C14N_1_1", INT2NUM(XML_C14N_1_1)); rb_define_method(cXMLDocument, "initialize", rxml_document_initialize, -1); rb_define_method(cXMLDocument, "canonicalize", rxml_document_canonicalize, -1); rb_define_method(cXMLDocument, "child", rxml_document_child_get, 0); rb_define_method(cXMLDocument, "child?", rxml_document_child_q, 0); rb_define_method(cXMLDocument, "compression", rxml_document_compression_get, 0); rb_define_method(cXMLDocument, "compression=", rxml_document_compression_set, 1); rb_define_method(cXMLDocument, "compression?", rxml_document_compression_q, 0); rb_define_method(cXMLDocument, "debug", rxml_document_debug, 0); rb_define_method(cXMLDocument, "encoding", rxml_document_encoding_get, 0); rb_define_method(cXMLDocument, "rb_encoding", rxml_document_rb_encoding_get, 0); rb_define_method(cXMLDocument, "encoding=", rxml_document_encoding_set, 1); rb_define_method(cXMLDocument, "import", rxml_document_import, 1); rb_define_method(cXMLDocument, "last", rxml_document_last_get, 0); rb_define_method(cXMLDocument, "last?", rxml_document_last_q, 0); rb_define_method(cXMLDocument, "next", rxml_document_next_get, 0); rb_define_method(cXMLDocument, "next?", rxml_document_next_q, 0); rb_define_method(cXMLDocument, "node_type", rxml_document_node_type, 0); rb_define_method(cXMLDocument, "order_elements!", rxml_document_order_elements, 0); rb_define_method(cXMLDocument, "parent", rxml_document_parent_get, 0); rb_define_method(cXMLDocument, "parent?", rxml_document_parent_q, 0); rb_define_method(cXMLDocument, "prev", rxml_document_prev_get, 0); rb_define_method(cXMLDocument, "prev?", rxml_document_prev_q, 0); rb_define_method(cXMLDocument, "root", rxml_document_root_get, 0); rb_define_method(cXMLDocument, "root=", rxml_document_root_set, 1); rb_define_method(cXMLDocument, "save", rxml_document_save, -1); rb_define_method(cXMLDocument, "standalone?", rxml_document_standalone_q, 0); rb_define_method(cXMLDocument, "to_s", rxml_document_to_s, -1); rb_define_method(cXMLDocument, "url", rxml_document_url_get, 0); rb_define_method(cXMLDocument, "version", rxml_document_version_get, 0); rb_define_method(cXMLDocument, "xhtml?", rxml_document_xhtml_q, 0); rb_define_method(cXMLDocument, "xinclude", rxml_document_xinclude, 0); rb_define_method(cXMLDocument, "validate", rxml_document_validate_dtd, 1); rb_define_method(cXMLDocument, "validate_schema", rxml_document_validate_schema, 1); rb_define_method(cXMLDocument, "validate_relaxng", rxml_document_validate_relaxng, 1); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_reader.c0000644000004100000410000011515113760147770021451 0ustar www-datawww-data/* Copyright (c) 2006-2007 Apple Inc. * Please see the LICENSE file for copyright and distribution information. */ #include "ruby_libxml.h" #include "ruby_xml_reader.h" /* * Document-class: LibXML::XML::Reader * * The XML::Reader class provides a simpler, alternative way of parsing an XML * document in contrast to XML::Parser or XML::SaxParser. A XML::Reader instance * acts like a cursor going forward in a document stream, stopping at each node * it encounters. To advance to the next node, simply cadd XML::Reader#read. * * The XML::Reader API closely matches the DOM Core specification and supports * namespaces, xml:base, entity handling and DTDs. * * To summarize, XML::Reader provides a far simpler API to use versus XML::SaxParser * and is more memory efficient than using XML::Parser to create a DOM tree. * * Example: * * reader = XML::Reader.string("123") * reader.read * assert_equal('foo', reader.name) * assert_nil(reader.value) * * 3.times do |i| * reader.read * assert_equal(XML::Reader::TYPE_ELEMENT, reader.node_type) * assert_equal('bar', reader.name) * reader.read * assert_equal(XML::Reader::TYPE_TEXT, reader.node_type) * assert_equal((i + 1).to_s, reader.value) * reader.read * assert_equal(XML::Reader::TYPE_END_ELEMENT, reader.node_type) * end * * You can also parse documents (see XML::Reader.document), * strings (see XML::Parser.string) and io objects (see * XML::Parser.io). * * For a more in depth tutorial, albeit in C, see http://xmlsoft.org/xmlreader.html.*/ /* NOTE - We need to wrap the readers document to support Reader.read.node.find('/'). To do this we need to use xmlTextReaderCurrentDoc which means we have to free the document ourselves. Annoying... */ VALUE cXMLReader; static ID BASE_URI_SYMBOL; static ID ENCODING_SYMBOL; static ID IO_ATTR; static ID OPTIONS_SYMBOL; static void rxml_reader_free(xmlTextReaderPtr xreader) { xmlFreeTextReader(xreader); } static void rxml_reader_mark(xmlTextReaderPtr xreader) { xmlDocPtr xdoc = xmlTextReaderCurrentDoc(xreader); VALUE doc = (VALUE)xdoc->_private; rb_gc_mark(doc); } static VALUE rxml_reader_wrap(xmlTextReaderPtr xreader) { return Data_Wrap_Struct(cXMLReader, NULL, rxml_reader_free, xreader); } static xmlTextReaderPtr rxml_text_reader_get(VALUE obj) { xmlTextReaderPtr xreader; Data_Get_Struct(obj, xmlTextReader, xreader); return xreader; } /* * call-seq: * XML::Reader.document(doc) -> XML::Reader * * Create an new reader for the specified document. */ VALUE rxml_reader_document(VALUE klass, VALUE doc) { xmlDocPtr xdoc; xmlTextReaderPtr xreader; Data_Get_Struct(doc, xmlDoc, xdoc); xreader = xmlReaderWalker(xdoc); if (xreader == NULL) rxml_raise(&xmlLastError); return rxml_reader_wrap(xreader); } /* call-seq: * XML::Reader.file(path) -> XML::Reader * XML::Reader.file(path, :encoding => XML::Encoding::UTF_8, * :options => XML::Parser::Options::NOENT) -> XML::Parser * * Creates a new reader by parsing the specified file or uri. * * You may provide an optional hash table to control how the * parsing is performed. Valid options are: * * encoding - The document encoding, defaults to nil. Valid values * are the encoding constants defined on XML::Encoding. * options - Controls the execution of the parser, defaults to 0. * Valid values are the constants defined on * XML::Parser::Options. Mutliple options can be combined * by using Bitwise OR (|). */ static VALUE rxml_reader_file(int argc, VALUE *argv, VALUE klass) { xmlTextReaderPtr xreader; VALUE path; VALUE options; const char *xencoding = NULL; int xoptions = 0; rb_scan_args(argc, argv, "11", &path, &options); Check_Type(path, T_STRING); if (!NIL_P(options)) { VALUE encoding = Qnil; VALUE parserOptions = Qnil; Check_Type(options, T_HASH); encoding = rb_hash_aref(options, BASE_URI_SYMBOL); xencoding = NIL_P(encoding) ? NULL : xmlGetCharEncodingName(NUM2INT(encoding)); parserOptions = rb_hash_aref(options, OPTIONS_SYMBOL); xoptions = NIL_P(parserOptions) ? 0 : NUM2INT(parserOptions); } xreader = xmlReaderForFile(StringValueCStr(path), xencoding, xoptions); if (xreader == NULL) rxml_raise(&xmlLastError); return rxml_reader_wrap(xreader); } /* call-seq: * XML::Reader.io(io) -> XML::Reader * XML::Reader.io(io, :encoding => XML::Encoding::UTF_8, * :options => XML::Parser::Options::NOENT) -> XML::Parser * * Creates a new reader by parsing the specified io object. * * You may provide an optional hash table to control how the * parsing is performed. Valid options are: * * base_uri - The base url for the parsed document. * encoding - The document encoding, defaults to nil. Valid values * are the encoding constants defined on XML::Encoding. * options - Controls the execution of the parser, defaults to 0. * Valid values are the constants defined on * XML::Parser::Options. Mutliple options can be combined * by using Bitwise OR (|). */ static VALUE rxml_reader_io(int argc, VALUE *argv, VALUE klass) { xmlTextReaderPtr xreader; VALUE result; VALUE io; VALUE options; char *xbaseurl = NULL; const char *xencoding = NULL; int xoptions = 0; rb_scan_args(argc, argv, "11", &io, &options); if (!NIL_P(options)) { VALUE baseurl = Qnil; VALUE encoding = Qnil; VALUE parserOptions = Qnil; Check_Type(options, T_HASH); baseurl = rb_hash_aref(options, BASE_URI_SYMBOL); xbaseurl = NIL_P(baseurl) ? NULL : StringValueCStr(baseurl); encoding = rb_hash_aref(options, ENCODING_SYMBOL); xencoding = NIL_P(encoding) ? NULL : xmlGetCharEncodingName(NUM2INT(encoding)); parserOptions = rb_hash_aref(options, OPTIONS_SYMBOL); xoptions = NIL_P(parserOptions) ? 0 : NUM2INT(parserOptions); } xreader = xmlReaderForIO((xmlInputReadCallback) rxml_read_callback, NULL, (void *) io, xbaseurl, xencoding, xoptions); if (xreader == NULL) rxml_raise(&xmlLastError); result = rxml_reader_wrap(xreader); /* Attach io object to parser so it won't get freed.*/ rb_ivar_set(result, IO_ATTR, io); return result; } /* call-seq: * XML::Reader.string(io) -> XML::Reader * XML::Reader.string(io, :encoding => XML::Encoding::UTF_8, * :options => XML::Parser::Options::NOENT) -> XML::Parser * * Creates a new reader by parsing the specified string. * * You may provide an optional hash table to control how the * parsing is performed. Valid options are: * * base_uri - The base url for the parsed document. * encoding - The document encoding, defaults to nil. Valid values * are the encoding constants defined on XML::Encoding. * options - Controls the execution of the parser, defaults to 0. * Valid values are the constants defined on * XML::Parser::Options. Mutliple options can be combined * by using Bitwise OR (|). */ static VALUE rxml_reader_string(int argc, VALUE *argv, VALUE klass) { xmlTextReaderPtr xreader; VALUE string; VALUE options; char *xbaseurl = NULL; const char *xencoding = NULL; int xoptions = 0; rb_scan_args(argc, argv, "11", &string, &options); Check_Type(string, T_STRING); if (!NIL_P(options)) { VALUE baseurl = Qnil; VALUE encoding = Qnil; VALUE parserOptions = Qnil; Check_Type(options, T_HASH); baseurl = rb_hash_aref(options, BASE_URI_SYMBOL); xbaseurl = NIL_P(baseurl) ? NULL : StringValueCStr(baseurl); encoding = rb_hash_aref(options, ENCODING_SYMBOL); xencoding = NIL_P(encoding) ? NULL : xmlGetCharEncodingName(NUM2INT(encoding)); parserOptions = rb_hash_aref(options, OPTIONS_SYMBOL); xoptions = NIL_P(parserOptions) ? 0 : NUM2INT(parserOptions); } xreader = xmlReaderForMemory(StringValueCStr(string), (int)RSTRING_LEN(string), xbaseurl, xencoding, xoptions); if (xreader == NULL) rxml_raise(&xmlLastError); return rxml_reader_wrap(xreader); } /* * call-seq: * reader.close -> code * * This method releases any resources allocated by the current instance * changes the state to Closed and close any underlying input. */ static VALUE rxml_reader_close(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderClose(xreader)); } /* * call-seq: * reader.move_to_attribute_no(index) -> code * * Move the position of the current instance to the attribute with the * specified index relative to the containing element. */ static VALUE rxml_reader_move_to_attr_no(VALUE self, VALUE index) { int ret; xmlTextReaderPtr xreader; xreader = rxml_text_reader_get(self); ret = xmlTextReaderMoveToAttributeNo(xreader, FIX2INT(index)); return INT2FIX(ret); } /* * call-seq: * reader.move_to_attribute(localName) -> code * * Move the position of the current instance to the attribute with the * specified name relative to the containing element. */ static VALUE rxml_reader_move_to_attr(VALUE self, VALUE val) { int ret; xmlTextReaderPtr xreader; xreader = rxml_text_reader_get(self); ret = xmlTextReaderMoveToAttribute(xreader, (const xmlChar *) StringValueCStr(val)); return INT2FIX(ret); } /* * call-seq: * reader.move_to_attribute_ns(localName, namespaceURI) -> code * * Move the position of the current instance to the attribute with the * specified name and namespace relative to the containing element. */ static VALUE rxml_reader_move_to_attr_ns(VALUE self, VALUE name, VALUE ns) { int ret; xmlTextReaderPtr xreader; xreader = rxml_text_reader_get(self); ret = xmlTextReaderMoveToAttributeNs(xreader, (const xmlChar *) StringValueCStr(name), (const xmlChar *) StringValueCStr(ns)); return INT2FIX(ret); } /* * call-seq: * reader.move_to_first_attribute -> code * * Move the position of the current instance to the first attribute associated * with the current node. */ static VALUE rxml_reader_move_to_first_attr(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderMoveToFirstAttribute(xreader)); } /* * call-seq: * reader.move_to_next_attribute -> code * * Move the position of the current instance to the next attribute associated * with the current node. */ static VALUE rxml_reader_move_to_next_attr(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderMoveToNextAttribute(xreader)); } /* * call-seq: * reader.move_to_element -> code * * Move the position of the current instance to the node that contains the * current attribute node. */ static VALUE rxml_reader_move_to_element(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderMoveToElement(xreader)); } /* * call-seq: * reader.next -> code * * Skip to the node following the current one in document order while avoiding * the subtree if any. */ static VALUE rxml_reader_next(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderNext(xreader)); } /* * call-seq: * reader.next_sibling -> code * * Skip to the node following the current one in document order while avoiding * the subtree if any. Currently implemented only for Readers built on a * document. */ static VALUE rxml_reader_next_sibling(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderNextSibling(xreader)); } /* * call-seq: * reader.node -> XML::Node * * Returns the reader's current node. It will return * nil if Reader#read has not yet been called. * WARNING - Using this method is dangerous because the * the node may be destroyed on the next #read. */ static VALUE rxml_reader_node(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); xmlNodePtr xnode = xmlTextReaderCurrentNode(xreader); return xnode ? rxml_node_wrap(xnode) : Qnil; } /* * call-seq: * reader.node_type -> type * * Get the node type of the current node. Reference: * http://dotgnu.org/pnetlib-doc/System/Xml/XmlNodeType.html */ static VALUE rxml_reader_node_type(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderNodeType(xreader)); } /* * call-seq: * reader.normalization -> value * * The value indicating whether to normalize white space and attribute values. * Since attribute value and end of line normalizations are a MUST in the XML * specification only the value true is accepted. The broken bahaviour of * accepting out of range character entities like � is of course not * supported either. * * Return 1 or -1 in case of error. */ static VALUE rxml_reader_normalization(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderNormalization(xreader)); } /* * call-seq: * reader.read -> nil|true|false * * Causes the reader to move to the next node in the stream, exposing its properties. * * Returns true if a node was successfully read or false if there are no more * nodes to read. On errors, an exception is raised.*/ static VALUE rxml_reader_read(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); int result = xmlTextReaderRead(xreader); switch(result) { case -1: rxml_raise(&xmlLastError); return Qnil; break; case 0: return Qfalse; case 1: return Qtrue; default: rb_raise(rb_eRuntimeError, "xmlTextReaderRead did not return -1, 0 or 1. Return value was: %d", result); } } /* * call-seq: * reader.read_attribute_value -> code * * Parse an attribute value into one or more Text and EntityReference nodes. * * Return 1 in case of success, 0 if the reader was not positionned on an * attribute node or all the attribute values have been read, or -1 in case of * error. */ static VALUE rxml_reader_read_attr_value(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderReadAttributeValue(xreader)); } /* * call-seq: * reader.read_inner_xml -> data * * Read the contents of the current node, including child nodes and markup. * * Return a string containing the XML content, or nil if the current node is * neither an element nor attribute, or has no child nodes. */ static VALUE rxml_reader_read_inner_xml(VALUE self) { VALUE result = Qnil; xmlTextReaderPtr xReader = rxml_text_reader_get(self); xmlChar *xml = xmlTextReaderReadInnerXml(xReader); if (xml) { const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); result = rxml_new_cstr( xml, xencoding); xmlFree(xml); } return result; } /* * call-seq: * reader.read_outer_xml -> data * * Read the contents of the current node, including child nodes and markup. * * Return a string containing the XML content, or nil if the current node is * neither an element nor attribute, or has no child nodes. */ static VALUE rxml_reader_read_outer_xml(VALUE self) { VALUE result = Qnil; xmlTextReaderPtr xReader = rxml_text_reader_get(self); xmlChar *xml = xmlTextReaderReadOuterXml(xReader); if (xml) { const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); result = rxml_new_cstr( xml, xencoding); xmlFree(xml); } return result; } /* * call-seq: * reader.read_state -> state * * Get the read state of the reader. */ static VALUE rxml_reader_read_state(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderReadState(xreader)); } /* * call-seq: * reader.read_string -> string * * Read the contents of an element or a text node as a string. * * Return a string containing the contents of the Element or Text node, or nil * if the reader is positioned on any other type of node. */ static VALUE rxml_reader_read_string(VALUE self) { VALUE result = Qnil; xmlTextReaderPtr xReader = rxml_text_reader_get(self); xmlChar *xml = xmlTextReaderReadString(xReader); if (xml) { const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); result = rxml_new_cstr( xml, xencoding); xmlFree(xml); } return result; } /* * call-seq: * reader.relax_ng_validate(rng) -> boolean * * Use RelaxNG to validate the document as it is processed. Activation is only * possible before the first read. If +rng+ is nil, the RelaxNG validation is * desactivated. * * Return true in case the RelaxNG validation could be (des)activated and false in * case of error. */ static VALUE rxml_reader_relax_ng_validate(VALUE self, VALUE rng) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); xmlRelaxNGPtr xrelax; int status; Data_Get_Struct(rng, xmlRelaxNG, xrelax); status = xmlTextReaderRelaxNGSetSchema(xreader, xrelax); return (status == 0 ? Qtrue : Qfalse); } #if LIBXML_VERSION >= 20620 /* * call-seq: * reader.schema_validate(schema) -> boolean * * Use W3C XSD schema to validate the document as it is processed. Activation * is only possible before the first read. If +schema+ is nil, then XML Schema * validation is deactivated. * * Return false if if the schema's validation could be (de)activated and true * otherwise. */ static VALUE rxml_reader_schema_validate(VALUE self, VALUE xsd) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); xmlSchemaPtr xschema; int status; Data_Get_Struct(xsd, xmlSchema, xschema); status = xmlTextReaderSetSchema(xreader, xschema); return (status == 0 ? Qtrue : Qfalse); } #endif /* * call-seq: * reader.name -> name * * Return the qualified name of the node. */ static VALUE rxml_reader_name(VALUE self) { xmlTextReaderPtr xReader = rxml_text_reader_get(self); const xmlChar *result = xmlTextReaderConstName(xReader); const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding)); } /* * call-seq: * reader.local_name -> name * * Return the local name of the node. */ static VALUE rxml_reader_local_name(VALUE self) { xmlTextReaderPtr xReader = rxml_text_reader_get(self); const xmlChar *result = xmlTextReaderConstLocalName(xReader); const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding)); } /* * call-seq: * reader.attribute_count -> count * * Provide the number of attributes of the current node. */ static VALUE rxml_reader_attr_count(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderAttributeCount(xreader)); } /* * call-seq: * reader.encoding -> XML::Encoding::UTF_8 * * Returns the encoding of the document being read. Note you * first have to read data from the reader for encoding * to return a value * * reader = XML::Reader.file(XML_FILE) * assert_nil(reader.encoding) * reader.read * assert_equal(XML::Encoding::UTF_8, reader.encoding) * * In addition, libxml always appears to return nil for the encoding * when parsing strings. */ static VALUE rxml_reader_encoding(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); const xmlChar *xencoding = xmlTextReaderConstEncoding(xreader); if (xencoding) return INT2NUM(xmlParseCharEncoding((const char*)xencoding)); else return INT2NUM(XML_CHAR_ENCODING_NONE); } /* * call-seq: * reader.base_uri -> URI * * Determine the base URI of the node. */ static VALUE rxml_reader_base_uri(VALUE self) { xmlTextReaderPtr xReader = rxml_text_reader_get(self); const xmlChar *result = xmlTextReaderConstBaseUri(xReader); const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding)); } /* * call-seq: * reader.namespace_uri -> URI * * Determine the namespace URI of the node. */ static VALUE rxml_reader_namespace_uri(VALUE self) { xmlTextReaderPtr xReader = rxml_text_reader_get(self); const xmlChar *result = xmlTextReaderConstNamespaceUri(xReader); const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding)); } /* * call-seq: * reader.value -> text * * Provide the text value of the node if present. */ static VALUE rxml_reader_value(VALUE self) { xmlTextReaderPtr xReader = rxml_text_reader_get(self); const xmlChar *result = xmlTextReaderConstValue(xReader); const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding)); } /* * call-seq: * reader.prefix -> prefix * * Get a shorthand reference to the namespace associated with the node. */ static VALUE rxml_reader_prefix(VALUE self) { xmlTextReaderPtr xReader = rxml_text_reader_get(self); const xmlChar *result = xmlTextReaderConstPrefix(xReader); const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding)); } /* * call-seq: * reader.depth -> depth * * Get the depth of the node in the tree. */ static VALUE rxml_reader_depth(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderDepth(xreader)); } /* * call-seq: * reader.quote_char -> char * * Get the quotation mark character used to enclose the value of an attribute, * as an integer value (and -1 in case of error). */ static VALUE rxml_reader_quote_char(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderQuoteChar(xreader)); } /* * call-seq: * reader.standalone -> code * * Determine the standalone status of the document being read. * * Return 1 if the document was declared to be standalone, 0 if it was * declared to be not standalone, or -1 if the document did not specify its * standalone status or in case of error. */ static VALUE rxml_reader_standalone(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2FIX(xmlTextReaderStandalone(xreader)); } /* * call-seq: * reader.xml_lang -> value * * Get the xml:lang scope within which the node resides. */ static VALUE rxml_reader_xml_lang(VALUE self) { xmlTextReaderPtr xReader = rxml_text_reader_get(self); const xmlChar *result = xmlTextReaderConstXmlLang(xReader); const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding)); } /* * call-seq: * reader.xml_version -> version * * Determine the XML version of the document being read. */ static VALUE rxml_reader_xml_version(VALUE self) { xmlTextReaderPtr xReader = rxml_text_reader_get(self); const xmlChar *result = xmlTextReaderConstXmlVersion(xReader); const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding)); } /* * call-seq: * reader.has_attributes? -> bool * * Get whether the node has attributes. */ static VALUE rxml_reader_has_attributes(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return xmlTextReaderHasAttributes(xreader) ? Qtrue : Qfalse; } /* * call-seq: * reader.has_value? -> bool * * Get whether the node can have a text value. */ static VALUE rxml_reader_has_value(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return xmlTextReaderHasValue(xreader) ? Qtrue : Qfalse; } /* * call-seq: * reader[key] -> value * * Provide the value of the attribute with the specified index (if +key+ is an * integer) or with the specified name (if +key+ is a string) relative to the * containing element, as a string. */ static VALUE rxml_reader_attribute(VALUE self, VALUE key) { VALUE result = Qnil; xmlChar *xattr; xmlTextReaderPtr xReader = rxml_text_reader_get(self); const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); if (TYPE(key) == T_FIXNUM) { xattr = xmlTextReaderGetAttributeNo(xReader, FIX2INT(key)); } else { xattr = xmlTextReaderGetAttribute(xReader, (const xmlChar *) StringValueCStr(key)); } if (xattr) { result = rxml_new_cstr(xattr, xencoding); xmlFree(xattr); } return result; } /* * call-seq: * reader.get_attribute(localName) -> value * * Provide the value of the attribute with the specified name * relative to the containing element. */ static VALUE rxml_reader_get_attribute(VALUE self, VALUE name) { VALUE result = Qnil; xmlChar *xattr; xmlTextReaderPtr xReader = rxml_text_reader_get(self); const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); xattr = xmlTextReaderGetAttribute(xReader, (const xmlChar *) StringValueCStr(name)); if (xattr) { result = rxml_new_cstr(xattr, xencoding); xmlFree(xattr); } return result; } /* * call-seq: * reader.get_attribute_no(index) -> value * * Provide the value of the attribute with the specified index * relative to the containing element. */ static VALUE rxml_reader_get_attribute_no(VALUE self, VALUE index) { VALUE result = Qnil; xmlChar *xattr; xmlTextReaderPtr xReader = rxml_text_reader_get(self); const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); xattr = xmlTextReaderGetAttributeNo(xReader, FIX2INT(index)); if (xattr) { result = rxml_new_cstr(xattr, xencoding); xmlFree(xattr); } return result; } static VALUE rxml_reader_get_attribute_ns(VALUE self, VALUE name, VALUE ns) { VALUE result = Qnil; xmlChar *xattr; xmlTextReaderPtr xReader = rxml_text_reader_get(self); const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); xattr = xmlTextReaderGetAttributeNs(xReader, (const xmlChar *) StringValueCStr(name), (const xmlChar *) StringValueCStr(ns)); if (xattr) { result = rxml_new_cstr(xattr, xencoding); xmlFree(xattr); } return result; } /* * call-seq: * reader.lookup_namespace(prefix) -> value * * Resolve a namespace prefix in the scope of the current element. * To return the default namespace, specify nil as +prefix+. */ static VALUE rxml_reader_lookup_namespace(VALUE self, VALUE prefix) { VALUE result = Qnil; xmlTextReaderPtr xReader = rxml_text_reader_get(self); const xmlChar *xnamespace = xmlTextReaderLookupNamespace(xReader, (const xmlChar *) StringValueCStr(prefix)); const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader); if (xnamespace) { result = rxml_new_cstr(xnamespace, xencoding); xmlFree((void *)xnamespace); } return result; } /* * call-seq: * reader.expand -> node * * Returns the current node and its full subtree. Note the returned node * is valid ONLY until the next read call. If you would like to preserve * the node, or search it via xpath, call reader.doc first. */ static VALUE rxml_reader_expand(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); xmlNodePtr xnode = xmlTextReaderExpand(xreader); if (!xnode) { return Qnil; } else { /* We cannot call rxml_node_wrap here because its sets up a mark function for the node. But according to the libxml docs (http://xmlsoft.org/html/libxml-xmlreader.html#xmlTextReaderExpand) this is only valid until the next xmlTextReaderRead call. At that point the node is freed (from reading the libxml2 source code. So don't set a mark or free function, because they will get called in the next garbage collection run and cause a segfault.*/ return Data_Wrap_Struct(cXMLNode, NULL, NULL, xnode); } } /* * call-seq: * reader.document -> doc * * Hacking interface that provides access to the current document being accessed by the * reader. NOTE: as a result of this call, the reader will not destroy the associated XML * document. Instead, it will be destroyed when the returned document goes out of scope. * * Returns: document */ static VALUE rxml_reader_doc(VALUE self) { VALUE result = Qnil; xmlTextReaderPtr xreader = rxml_text_reader_get(self); xmlDocPtr xdoc = xmlTextReaderCurrentDoc(xreader); if (!xdoc) rb_raise(rb_eRuntimeError, "The reader does not have a document. Did you forget to call read?"); result = rxml_document_wrap(xdoc); // And now hook in a mark function to keep the document alive as long as the reader is valid RDATA(self)->dmark = (RUBY_DATA_FUNC)rxml_reader_mark; return result; } #if LIBXML_VERSION >= 20618 /* * call-seq: * reader.byte_consumed -> value * * This method provides the current index of the parser used by the reader, * relative to the start of the current entity. */ static VALUE rxml_reader_byte_consumed(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2NUM(xmlTextReaderByteConsumed(xreader)); } #endif #if LIBXML_VERSION >= 20617 /* * call-seq: * reader.column_number -> number * * Provide the column number of the current parsing point. */ static VALUE rxml_reader_column_number(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2NUM(xmlTextReaderGetParserColumnNumber(xreader)); } /* * call-seq: * reader.line_number -> number * * Provide the line number of the current parsing point. */ static VALUE rxml_reader_line_number(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return INT2NUM(xmlTextReaderGetParserLineNumber(xreader)); } #endif /* * call-seq: * reader.default? -> bool * * Return whether an Attribute node was generated from the default value * defined in the DTD or schema. */ static VALUE rxml_reader_default(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return xmlTextReaderIsDefault(xreader) ? Qtrue : Qfalse; } /* * call-seq: * reader.namespace_declaration? -> bool * * Determine whether the current node is a namespace declaration rather than a * regular attribute. */ static VALUE rxml_reader_namespace_declaration(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return xmlTextReaderIsNamespaceDecl(xreader) ? Qtrue : Qfalse; } /* * call-seq: * reader.empty_element? -> bool * * Check if the current node is empty. */ static VALUE rxml_reader_empty_element(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return xmlTextReaderIsEmptyElement(xreader) ? Qtrue : Qfalse; } /* * call-seq: * reader.valid? -> bool * * Retrieve the validity status from the parser context. */ static VALUE rxml_reader_valid(VALUE self) { xmlTextReaderPtr xreader = rxml_text_reader_get(self); return xmlTextReaderIsValid(xreader) ? Qtrue : Qfalse; } void rxml_init_reader(void) { BASE_URI_SYMBOL = ID2SYM(rb_intern("base_uri")); ENCODING_SYMBOL = ID2SYM(rb_intern("encoding")); IO_ATTR = rb_intern("@io"); OPTIONS_SYMBOL = ID2SYM(rb_intern("options")); cXMLReader = rb_define_class_under(mXML, "Reader", rb_cObject); rb_define_singleton_method(cXMLReader, "document", rxml_reader_document, 1); rb_define_singleton_method(cXMLReader, "file", rxml_reader_file, -1); rb_define_singleton_method(cXMLReader, "io", rxml_reader_io, -1); rb_define_singleton_method(cXMLReader, "string", rxml_reader_string, -1); rb_define_method(cXMLReader, "[]", rxml_reader_attribute, 1); rb_define_method(cXMLReader, "attribute_count", rxml_reader_attr_count, 0); rb_define_method(cXMLReader, "base_uri", rxml_reader_base_uri, 0); #if LIBXML_VERSION >= 20618 rb_define_method(cXMLReader, "byte_consumed", rxml_reader_byte_consumed, 0); #endif rb_define_method(cXMLReader, "close", rxml_reader_close, 0); #if LIBXML_VERSION >= 20617 rb_define_method(cXMLReader, "column_number", rxml_reader_column_number, 0); #endif rb_define_method(cXMLReader, "depth", rxml_reader_depth, 0); rb_define_method(cXMLReader, "doc", rxml_reader_doc, 0); rb_define_method(cXMLReader, "encoding", rxml_reader_encoding, 0); rb_define_method(cXMLReader, "expand", rxml_reader_expand, 0); rb_define_method(cXMLReader, "get_attribute", rxml_reader_get_attribute, 1); rb_define_method(cXMLReader, "get_attribute_no", rxml_reader_get_attribute_no, 1); rb_define_method(cXMLReader, "get_attribute_ns", rxml_reader_get_attribute_ns, 2); rb_define_method(cXMLReader, "has_attributes?", rxml_reader_has_attributes, 0); rb_define_method(cXMLReader, "has_value?", rxml_reader_has_value, 0); #if LIBXML_VERSION >= 20617 rb_define_method(cXMLReader, "line_number", rxml_reader_line_number, 0); #endif rb_define_method(cXMLReader, "local_name", rxml_reader_local_name, 0); rb_define_method(cXMLReader, "lookup_namespace", rxml_reader_lookup_namespace, 1); rb_define_method(cXMLReader, "move_to_attribute", rxml_reader_move_to_attr, 1); rb_define_method(cXMLReader, "move_to_attribute_no", rxml_reader_move_to_attr_no, 1); rb_define_method(cXMLReader, "move_to_attribute_ns", rxml_reader_move_to_attr_ns, 2); rb_define_method(cXMLReader, "move_to_first_attribute", rxml_reader_move_to_first_attr, 0); rb_define_method(cXMLReader, "move_to_next_attribute", rxml_reader_move_to_next_attr, 0); rb_define_method(cXMLReader, "move_to_element", rxml_reader_move_to_element, 0); rb_define_method(cXMLReader, "name", rxml_reader_name, 0); rb_define_method(cXMLReader, "namespace_uri", rxml_reader_namespace_uri, 0); rb_define_method(cXMLReader, "next", rxml_reader_next, 0); rb_define_method(cXMLReader, "next_sibling", rxml_reader_next_sibling, 0); rb_define_method(cXMLReader, "node", rxml_reader_node, 0); rb_define_method(cXMLReader, "node_type", rxml_reader_node_type, 0); rb_define_method(cXMLReader, "normalization", rxml_reader_normalization, 0); rb_define_method(cXMLReader, "prefix", rxml_reader_prefix, 0); rb_define_method(cXMLReader, "quote_char", rxml_reader_quote_char, 0); rb_define_method(cXMLReader, "read", rxml_reader_read, 0); rb_define_method(cXMLReader, "read_attribute_value", rxml_reader_read_attr_value, 0); rb_define_method(cXMLReader, "read_inner_xml", rxml_reader_read_inner_xml, 0); rb_define_method(cXMLReader, "read_outer_xml", rxml_reader_read_outer_xml, 0); rb_define_method(cXMLReader, "read_state", rxml_reader_read_state, 0); rb_define_method(cXMLReader, "read_string", rxml_reader_read_string, 0); rb_define_method(cXMLReader, "relax_ng_validate", rxml_reader_relax_ng_validate, 1); rb_define_method(cXMLReader, "standalone", rxml_reader_standalone, 0); #if LIBXML_VERSION >= 20620 rb_define_method(cXMLReader, "schema_validate", rxml_reader_schema_validate, 1); #endif rb_define_method(cXMLReader, "value", rxml_reader_value, 0); rb_define_method(cXMLReader, "xml_lang", rxml_reader_xml_lang, 0); rb_define_method(cXMLReader, "xml_version", rxml_reader_xml_version, 0); rb_define_method(cXMLReader, "default?", rxml_reader_default, 0); rb_define_method(cXMLReader, "empty_element?", rxml_reader_empty_element, 0); rb_define_method(cXMLReader, "namespace_declaration?", rxml_reader_namespace_declaration, 0); rb_define_method(cXMLReader, "valid?", rxml_reader_valid, 0); /* Constants */ rb_define_const(cXMLReader, "LOADDTD", INT2FIX(XML_PARSER_LOADDTD)); rb_define_const(cXMLReader, "DEFAULTATTRS", INT2FIX(XML_PARSER_DEFAULTATTRS)); rb_define_const(cXMLReader, "VALIDATE", INT2FIX(XML_PARSER_VALIDATE)); rb_define_const(cXMLReader, "SUBST_ENTITIES", INT2FIX(XML_PARSER_SUBST_ENTITIES)); rb_define_const(cXMLReader, "SEVERITY_VALIDITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_WARNING)); rb_define_const(cXMLReader, "SEVERITY_VALIDITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_ERROR)); rb_define_const(cXMLReader, "SEVERITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_WARNING)); rb_define_const(cXMLReader, "SEVERITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_ERROR)); rb_define_const(cXMLReader, "TYPE_NONE", INT2FIX(XML_READER_TYPE_NONE)); rb_define_const(cXMLReader, "TYPE_ELEMENT", INT2FIX(XML_READER_TYPE_ELEMENT)); rb_define_const(cXMLReader, "TYPE_ATTRIBUTE", INT2FIX(XML_READER_TYPE_ATTRIBUTE)); rb_define_const(cXMLReader, "TYPE_TEXT", INT2FIX(XML_READER_TYPE_TEXT)); rb_define_const(cXMLReader, "TYPE_CDATA", INT2FIX(XML_READER_TYPE_CDATA)); rb_define_const(cXMLReader, "TYPE_ENTITY_REFERENCE", INT2FIX(XML_READER_TYPE_ENTITY_REFERENCE)); rb_define_const(cXMLReader, "TYPE_ENTITY", INT2FIX(XML_READER_TYPE_ENTITY)); rb_define_const(cXMLReader, "TYPE_PROCESSING_INSTRUCTION", INT2FIX(XML_READER_TYPE_PROCESSING_INSTRUCTION)); rb_define_const(cXMLReader, "TYPE_COMMENT", INT2FIX(XML_READER_TYPE_COMMENT)); rb_define_const(cXMLReader, "TYPE_DOCUMENT", INT2FIX(XML_READER_TYPE_DOCUMENT)); rb_define_const(cXMLReader, "TYPE_DOCUMENT_TYPE", INT2FIX(XML_READER_TYPE_DOCUMENT_TYPE)); rb_define_const(cXMLReader, "TYPE_DOCUMENT_FRAGMENT", INT2FIX(XML_READER_TYPE_DOCUMENT_FRAGMENT)); rb_define_const(cXMLReader, "TYPE_NOTATION", INT2FIX(XML_READER_TYPE_NOTATION)); rb_define_const(cXMLReader, "TYPE_WHITESPACE", INT2FIX(XML_READER_TYPE_WHITESPACE)); rb_define_const(cXMLReader, "TYPE_SIGNIFICANT_WHITESPACE", INT2FIX(XML_READER_TYPE_SIGNIFICANT_WHITESPACE)); rb_define_const(cXMLReader, "TYPE_END_ELEMENT", INT2FIX(XML_READER_TYPE_END_ELEMENT)); rb_define_const(cXMLReader, "TYPE_END_ENTITY", INT2FIX(XML_READER_TYPE_END_ENTITY)); rb_define_const(cXMLReader, "TYPE_XML_DECLARATION", INT2FIX(XML_READER_TYPE_XML_DECLARATION)); /* Read states */ rb_define_const(cXMLReader, "MODE_INITIAL", INT2FIX(XML_TEXTREADER_MODE_INITIAL)); rb_define_const(cXMLReader, "MODE_INTERACTIVE", INT2FIX(XML_TEXTREADER_MODE_INTERACTIVE)); rb_define_const(cXMLReader, "MODE_ERROR", INT2FIX(XML_TEXTREADER_MODE_ERROR)); rb_define_const(cXMLReader, "MODE_EOF", INT2FIX(XML_TEXTREADER_MODE_EOF)); rb_define_const(cXMLReader, "MODE_CLOSED", INT2FIX(XML_TEXTREADER_MODE_CLOSED)); rb_define_const(cXMLReader, "MODE_READING", INT2FIX(XML_TEXTREADER_MODE_READING)); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_html_parser_options.h0000644000004100000410000000037213760147770024305 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_HTML_PARSER_OPTIONS__ #define __RXML_HTML_PARSER_OPTIONS__ extern VALUE mXMLHtmlParserOptions; void rxml_init_html_parser_options(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_parser.h0000644000004100000410000000035213760147770021504 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_PARSER__ #define __RXML_PARSER__ #define MAX_LIBXML_FEATURES_LEN 50 extern VALUE cXMLParser; void rxml_init_parser(); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_relaxng.c0000644000004100000410000000604013760147770021643 0ustar www-datawww-data#include "ruby_libxml.h" #include "ruby_xml_relaxng.h" /* * Document-class: LibXML::XML::RelaxNG * * The XML::RelaxNG class is used to prepare RelaxNG schemas for validation * of xml documents. * * Schemas can be created from XML documents, strings or URIs using the * corresponding methods (new for URIs). * * Once a schema is prepared, an XML document can be validated by the * XML::Document#validate_relaxng method providing the XML::RelaxNG object * as parameter. The method will raise an exception if the document is * not valid. * * Basic Usage: * * # parse schema as xml document * relaxng_document = XML::Document.file('schema.rng') * * # prepare schema for validation * relaxng_schema = XML::RelaxNG.document(relaxng_document) * * # parse xml document to be validated * instance = XML::Document.file('instance.xml') * * # validate * instance.validate_relaxng(relaxng_schema) */ VALUE cXMLRelaxNG; static void rxml_relaxng_free(xmlRelaxNGPtr xrelaxng) { xmlRelaxNGFree(xrelaxng); } /* * call-seq: * XML::Relaxng.new(relaxng_uri) -> relaxng * * Create a new relaxng from the specified URI. */ static VALUE rxml_relaxng_init_from_uri(VALUE class, VALUE uri) { xmlRelaxNGParserCtxtPtr xparser; xmlRelaxNGPtr xrelaxng; Check_Type(uri, T_STRING); xparser = xmlRelaxNGNewParserCtxt(StringValuePtr(uri)); xrelaxng = xmlRelaxNGParse(xparser); xmlRelaxNGFreeParserCtxt(xparser); return Data_Wrap_Struct(cXMLRelaxNG, NULL, rxml_relaxng_free, xrelaxng); } /* * call-seq: * XML::RelaxNG.document(document) -> relaxng * * Create a new relaxng from the specified document. */ static VALUE rxml_relaxng_init_from_document(VALUE class, VALUE document) { xmlDocPtr xdoc; xmlRelaxNGPtr xrelaxng; xmlRelaxNGParserCtxtPtr xparser; Data_Get_Struct(document, xmlDoc, xdoc); xparser = xmlRelaxNGNewDocParserCtxt(xdoc); xrelaxng = xmlRelaxNGParse(xparser); xmlRelaxNGFreeParserCtxt(xparser); return Data_Wrap_Struct(cXMLRelaxNG, NULL, rxml_relaxng_free, xrelaxng); } /* * call-seq: * XML::RelaxNG.string("relaxng_data") -> "value" * * Create a new relaxng using the specified string. */ static VALUE rxml_relaxng_init_from_string(VALUE self, VALUE relaxng_str) { xmlRelaxNGParserCtxtPtr xparser; xmlRelaxNGPtr xrelaxng; Check_Type(relaxng_str, T_STRING); xparser = xmlRelaxNGNewMemParserCtxt(StringValuePtr(relaxng_str), (int)strlen(StringValuePtr(relaxng_str))); xrelaxng = xmlRelaxNGParse(xparser); xmlRelaxNGFreeParserCtxt(xparser); return Data_Wrap_Struct(cXMLRelaxNG, NULL, rxml_relaxng_free, xrelaxng); } void rxml_init_relaxng(void) { cXMLRelaxNG = rb_define_class_under(mXML, "RelaxNG", rb_cObject); rb_define_singleton_method(cXMLRelaxNG, "new", rxml_relaxng_init_from_uri, 1); rb_define_singleton_method(cXMLRelaxNG, "from_string", rxml_relaxng_init_from_string, 1); rb_define_singleton_method(cXMLRelaxNG, "document", rxml_relaxng_init_from_document, 1); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_dtd.h0000644000004100000410000000022313760147770020760 0ustar www-datawww-data#ifndef __RXML_DTD__ #define __RXML_DTD__ extern VALUE cXMLDtd; void rxml_init_dtd(void); VALUE rxml_dtd_wrap(xmlDtdPtr xdtd); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_namespaces.c0000644000004100000410000002012013760147770022315 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include "ruby_libxml.h" #include "ruby_xml_namespaces.h" VALUE cXMLNamespaces; /* Document-class: LibXML::XML::Namespaces * * The XML::Namespaces class is used to access information about * a node's namespaces. For each node, libxml maintains: * * * The node's namespace (#namespace) * * Which namespaces are defined on the node (#definnitions) * * Which namespaces are in scope for the node (#each) * * Let's look at an example: * * * * * * * * The Envelope node is in the soap namespace. It contains * two namespace definitions, one for soap and one for xsd. * * The Body node is also in the soap namespace and does not * contain any namespaces. However, the soap and xsd namespaces * are both in context. * * The order node is in its default namespace and contains * one namespace definition (http://mynamespace.com). There * are three namespaces in context soap, xsd and the * default namespace. */ static VALUE rxml_namespaces_alloc(VALUE klass) { return Data_Wrap_Struct(klass, NULL, NULL, NULL); } /* * call-seq: * initialize(XML::Node) -> XML::Namespaces * * Creates a new namespaces object. Generally you * do not call this method directly, but instead * access a namespaces object via XML::Node#namespaces. * * Usage: * * doc = XML::Document.string('') * namespaces = new XML::Namespaces(doc.root) */ static VALUE rxml_namespaces_initialize(VALUE self, VALUE node) { xmlNodePtr xnode; Check_Type(node, T_DATA); Data_Get_Struct(node, xmlNode, xnode); DATA_PTR(self) = xnode; return self; } /* * call-seq: * namespaces.definitions -> [XML::Namespace, XML::Namespace] * * Returns an array of XML::Namespace objects that are * defined on this node. * * Usage: * * doc = XML::Document.string('') * defs = doc.root.namespaces.definitions */ static VALUE rxml_namespaces_definitions(VALUE self) { xmlNodePtr xnode; xmlNsPtr xns; VALUE arr; Data_Get_Struct(self, xmlNode, xnode); arr = rb_ary_new(); xns = xnode->nsDef; while (xns) { VALUE anamespace = rxml_namespace_wrap(xns); rb_ary_push(arr, anamespace); xns = xns->next; } return arr; } /* * call-seq: * namespaces.each {|XML::Namespace|} * * Iterates over the namespace objects that are * in context for this node. * * Usage: * * doc = XML::Document.string('') * doc.root.namespaces.each do |ns| * .. * end */ static VALUE rxml_namespaces_each(VALUE self) { xmlNodePtr xnode; xmlNsPtr *nsList, *xns; Data_Get_Struct(self, xmlNode, xnode); nsList = xmlGetNsList(xnode->doc, xnode); if (nsList == NULL) return (Qnil); for (xns = nsList; *xns != NULL; xns++) { VALUE ns = rxml_namespace_wrap(*xns); rb_yield(ns); } xmlFree(nsList); return Qnil; } /* * call-seq: * namespaces.find_by_href(href) -> XML::Namespace * * Searches for a namespace that has the specified href. * The search starts at the current node and works upward * through the node's parents. If a namespace is found, * then an XML::Namespace instance is returned, otherwise nil * is returned. * * Usage: * * doc = XML::Document.string('') * ns = doc.root.namespaces.find_by_href('http://schemas.xmlsoap.org/soap/envelope/') * assert_equal('soap', ns.prefix) * assert_equal('http://schemas.xmlsoap.org/soap/envelope/', ns.href) */ static VALUE rxml_namespaces_find_by_href(VALUE self, VALUE href) { xmlNodePtr xnode; xmlNsPtr xns; Check_Type(href, T_STRING); Data_Get_Struct(self, xmlNode, xnode); xns = xmlSearchNsByHref(xnode->doc, xnode, (xmlChar*) StringValuePtr(href)); if (xns) return rxml_namespace_wrap(xns); else return Qnil; } /* * call-seq: * namespaces.find_by_prefix(prefix=nil) -> XML::Namespace * * Searches for a namespace that has the specified prefix. * The search starts at the current node and works upward * through the node's parents. If a namespace is found, * then an XML::Namespace instance is returned, otherwise nil * is returned. * * Usage: * * doc = XML::Document.string('') * ns = doc.root.namespaces.find_by_prefix('soap') * assert_equal('soap', ns.prefix) * assert_equal('http://schemas.xmlsoap.org/soap/envelope/', ns.href) */ static VALUE rxml_namespaces_find_by_prefix(VALUE self, VALUE prefix) { xmlNodePtr xnode; xmlNsPtr xns; xmlChar* xprefix = NULL; if (!NIL_P(prefix)) { Check_Type(prefix, T_STRING); xprefix = (xmlChar*) StringValuePtr(prefix); } Data_Get_Struct(self, xmlNode, xnode); xns = xmlSearchNs(xnode->doc, xnode, xprefix); if (xns) return rxml_namespace_wrap(xns); else return Qnil; } /* * call-seq: * namespaces.namespace -> XML::Namespace * * Returns the current node's namespace. * * Usage: * * doc = XML::Document.string('') * ns = doc.root.namespaces.namespace * assert_equal('soap', ns.prefix) * assert_equal('http://schemas.xmlsoap.org/soap/envelope/', ns.href) */ static VALUE rxml_namespaces_namespace_get(VALUE self) { xmlNodePtr xnode; Data_Get_Struct(self, xmlNode, xnode); if (xnode->ns) return rxml_namespace_wrap(xnode->ns); else return Qnil; } /* * call-seq: * namespaces.namespace = XML::Namespace * * Sets the current node's namespace. * * Basic usage: * * # Create a node * node = XML::Node.new('Envelope') * * # Define the soap namespace - this does *not* put the node in the namespace * ns = XML::Namespace.new(node, 'soap', 'http://schemas.xmlsoap.org/soap/envelope/') * assert_equal("", node.to_s) * * # Now put the node in the soap namespace, not how the string representation changes * node.namespaces.namespace = ns * assert_equal("", node.to_s) */ static VALUE rxml_namespaces_namespace_set(VALUE self, VALUE ns) { xmlNodePtr xnode; xmlNsPtr xns; Data_Get_Struct(self, xmlNode, xnode); Check_Type(ns, T_DATA); Data_Get_Struct(ns, xmlNs, xns); xmlSetNs(xnode, xns); return self; } /* * call-seq: * namespaces.node -> XML::Node * * Returns the current node. */ static VALUE rxml_namespaces_node_get(VALUE self) { xmlNodePtr xnode; Data_Get_Struct(self, xmlNode, xnode); return rxml_node_wrap(xnode); } void rxml_init_namespaces(void) { cXMLNamespaces = rb_define_class_under(mXML, "Namespaces", rb_cObject); rb_include_module(cXMLNamespaces, rb_mEnumerable); rb_define_alloc_func(cXMLNamespaces, rxml_namespaces_alloc); rb_define_method(cXMLNamespaces, "initialize", rxml_namespaces_initialize, 1); rb_define_method(cXMLNamespaces, "definitions", rxml_namespaces_definitions, 0); rb_define_method(cXMLNamespaces, "each", rxml_namespaces_each, 0); rb_define_method(cXMLNamespaces, "find_by_href", rxml_namespaces_find_by_href, 1); rb_define_method(cXMLNamespaces, "find_by_prefix", rxml_namespaces_find_by_prefix, 1); rb_define_method(cXMLNamespaces, "namespace", rxml_namespaces_namespace_get, 0); rb_define_method(cXMLNamespaces, "namespace=", rxml_namespaces_namespace_set, 1); rb_define_method(cXMLNamespaces, "node", rxml_namespaces_node_get, 0); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_sax_parser.h0000644000004100000410000000032713760147770022361 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_SAX_PARSER__ #define __RXML_SAX_PARSER__ extern VALUE cXMLSaxParser; void rxml_init_sax_parser(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_version.h0000644000004100000410000000062613760147770021701 0ustar www-datawww-data/* Don't nuke this block! It is used for automatically updating the * versions below. VERSION = string formatting, VERNUM = numbered * version for inline testing: increment both or none at all.*/ #define RUBY_LIBXML_VERSION "3.2.1" #define RUBY_LIBXML_VERNUM 321 #define RUBY_LIBXML_VER_MAJ 3 #define RUBY_LIBXML_VER_MIN 2 #define RUBY_LIBXML_VER_MIC 1 #define RUBY_LIBXML_VER_PATCH 0 libxml-ruby-3.2.1/ext/libxml/ruby_xml_schema_attribute.c0000644000004100000410000000604213760147770023530 0ustar www-datawww-data#include "ruby_libxml.h" #include "ruby_xml_schema_attribute.h" #include "ruby_xml_schema_type.h" VALUE cXMLSchemaAttribute; static void rxml_schema_attribute_free(xmlSchemaAttributeUsePtr attr) { attr = NULL; xmlFree(attr); } VALUE rxml_wrap_schema_attribute(xmlSchemaAttributeUsePtr attr) { return Data_Wrap_Struct(cXMLSchemaAttribute, NULL, rxml_schema_attribute_free, attr); } static VALUE rxml_schema_attribute_namespace(VALUE self) { xmlSchemaAttributeUsePtr attr; const xmlChar *tns; Data_Get_Struct(self, xmlSchemaAttributeUse, attr); if (attr == NULL) return Qnil; if (attr->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { tns = ((xmlSchemaAttributeUseProhibPtr) attr)->targetNamespace; } else if (attr->type == XML_SCHEMA_EXTRA_QNAMEREF) { tns = ((xmlSchemaQNameRefPtr) attr)->targetNamespace; } else { tns = ((xmlSchemaAttributePtr) ((xmlSchemaAttributeUsePtr) (attr))->attrDecl)->targetNamespace; } QNIL_OR_STRING(tns) } static VALUE rxml_schema_attribute_name(VALUE self) { xmlSchemaAttributeUsePtr attr; const xmlChar *name; Data_Get_Struct(self, xmlSchemaAttributeUse, attr); if (attr == NULL) return Qnil; if (attr->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { name = ((xmlSchemaAttributeUseProhibPtr) attr)->name; } else if (attr->type == XML_SCHEMA_EXTRA_QNAMEREF) { name = ((xmlSchemaQNameRefPtr) attr)->name; } else { xmlSchemaAttributePtr attrDecl = ((xmlSchemaAttributeUsePtr) attr)->attrDecl; name = attrDecl->name; } QNIL_OR_STRING(name) } static VALUE rxml_schema_attribute_type(VALUE self) { xmlSchemaAttributeUsePtr attr; xmlSchemaTypePtr xtype; Data_Get_Struct(self, xmlSchemaAttributeUse, attr); xtype = attr->attrDecl->subtypes; return rxml_wrap_schema_type((xmlSchemaTypePtr) xtype); } static VALUE rxml_schema_attribute_node(VALUE self) { xmlSchemaAttributeUsePtr attr; Data_Get_Struct(self, xmlSchemaAttributeUse, attr); return rxml_node_wrap(attr->node); } static VALUE rxml_schema_attribute_value(VALUE self) { xmlSchemaAttributeUsePtr attr; Data_Get_Struct(self, xmlSchemaAttributeUse, attr); QNIL_OR_STRING(attr->defValue) } static VALUE rxml_schema_attribute_occurs(VALUE self) { xmlSchemaAttributeUsePtr attr; Data_Get_Struct(self, xmlSchemaAttributeUse, attr); return INT2NUM(attr->occurs); } void rxml_init_schema_attribute(void) { cXMLSchemaAttribute = rb_define_class_under(cXMLSchema, "Attribute", rb_cObject); rb_define_method(cXMLSchemaAttribute, "namespace", rxml_schema_attribute_namespace, 0); rb_define_method(cXMLSchemaAttribute, "name", rxml_schema_attribute_name, 0); rb_define_method(cXMLSchemaAttribute, "type", rxml_schema_attribute_type, 0); rb_define_method(cXMLSchemaAttribute, "node", rxml_schema_attribute_node, 0); rb_define_method(cXMLSchemaAttribute, "value", rxml_schema_attribute_value, 0); rb_define_method(cXMLSchemaAttribute, "occurs", rxml_schema_attribute_occurs, 0); } libxml-ruby-3.2.1/ext/libxml/libxml_ruby.def0000644000004100000410000000122113760147770021122 0ustar www-datawww-dataLIBRARY libxml_ruby.so EXPORTS Init_libxml_ruby rxml_document_wrap rxml_xpath_to_value rxml_xpath_from_value cXMLAttr DATA cXMLAttrDecl DATA cXMLAttributes DATA cXMLDocument DATA cXMLDtd DATA cXMLHtmlParser DATA cXMLHtmlParserContext DATA cXMLNamespace DATA cXMLNamespaces DATA cXMLNode DATA cXMLParser DATA cXMLParserContext DATA cXMLReader DATA cXMLRelaxNG DATA cXMLSaxParser DATA cXMLSchema DATA cXMLXInclude DATA cXMLXPathContext DATA cXMLXPathExpression DATA cXMLXPathObject DATA cXMLXPointer DATA eXMLError DATA mLibXML DATA mXML DATA mXMLEncoding DATA mXMLHtmlParserOptions DATA mXMLParserOptions DATA mXPath DATA libxml-ruby-3.2.1/ext/libxml/ruby_xml_xpath_context.h0000644000004100000410000000034113760147770023076 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_XPATH_CONTEXT__ #define __RXML_XPATH_CONTEXT__ extern VALUE cXMLXPathContext; void rxml_init_xpath_context(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_html_parser_options.c0000644000004100000410000000352413760147770024302 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include "ruby_libxml.h" /* Document-class: LibXML::XML::HTMLParser::Options * * Options to control the operation of the HTMLParser. The easiest * way to set a parser's options is via the methods * XML::HTMLParser.file, XML::HTMLParser.io or XML::HTMLParser.string. * For additional control, see XML::HTMLParser::Context#options=. */ VALUE mXMLHtmlParserOptions; void rxml_init_html_parser_options(void) { mXMLHtmlParserOptions = rb_define_module_under(cXMLHtmlParser, "Options"); #if LIBXML_VERSION >= 20621 /* 1: Relax parsing. */ rb_define_const(mXMLHtmlParserOptions, "RECOVER", INT2NUM(HTML_PARSE_RECOVER)); #endif #if LIBXML_VERSION >= 20708 /* 2: Do not default a doctype if not found */ rb_define_const(mXMLHtmlParserOptions, "NODEFDTD", INT2NUM(HTML_PARSE_NODEFDTD)); #endif /* 32: Suppress error reports. */ rb_define_const(mXMLHtmlParserOptions, "NOERROR", INT2NUM(HTML_PARSE_NOERROR)); /* 64: Suppress warning reports. */ rb_define_const(mXMLHtmlParserOptions, "NOWARNING", INT2NUM(HTML_PARSE_NOWARNING)); /* 128: Enable pedantic error reporting. */ rb_define_const(mXMLHtmlParserOptions, "PEDANTIC", INT2NUM(HTML_PARSE_PEDANTIC)); /* 256: Remove blank nodes. */ rb_define_const(mXMLHtmlParserOptions, "NOBLANKS", INT2NUM(HTML_PARSE_NOBLANKS)); #if LIBXML_VERSION >= 20621 /* 2048: Forbid network access. */ rb_define_const(mXMLHtmlParserOptions, "NONET", INT2NUM(HTML_PARSE_NONET)); /* 65536: Compact small text nodes. */ rb_define_const(mXMLHtmlParserOptions, "COMPACT", INT2NUM(HTML_PARSE_COMPACT)); #endif #if LIBXML_VERSION >= 20707 /* 8192: Do not add implied html/body... elements */ rb_define_const(mXMLHtmlParserOptions, "NOIMPLIED", INT2NUM(HTML_PARSE_NOIMPLIED)); #endif } libxml-ruby-3.2.1/ext/libxml/ruby_xml_xinclude.c0000644000004100000410000000051213760147770022014 0ustar www-datawww-data#include "ruby_libxml.h" #include "ruby_xml_xinclude.h" VALUE cXMLXInclude; /* * Document-class: LibXML::XML::XInclude * * The ruby bindings do not currently expose libxml's * XInclude fuctionality. */ void rxml_init_xinclude(void) { cXMLXInclude = rb_define_class_under(mXML, "XInclude", rb_cObject); } libxml-ruby-3.2.1/ext/libxml/ruby_libxml.h0000644000004100000410000000346013760147770020622 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RUBY_LIBXML_H__ #define __RUBY_LIBXML_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef LIBXML_DEBUG_ENABLED #include #endif #ifdef LIBXML_XINCLUDE_ENABLED #include #endif #ifdef LIBXML_XPTR_ENABLED #include #endif #include "ruby_xml_version.h" #include "ruby_xml.h" #include "ruby_xml_io.h" #include "ruby_xml_error.h" #include "ruby_xml_encoding.h" #include "ruby_xml_attributes.h" #include "ruby_xml_attr.h" #include "ruby_xml_attr_decl.h" #include "ruby_xml_document.h" #include "ruby_xml_node.h" #include "ruby_xml_namespace.h" #include "ruby_xml_namespaces.h" #include "ruby_xml_parser.h" #include "ruby_xml_parser_options.h" #include "ruby_xml_parser_context.h" #include "ruby_xml_html_parser.h" #include "ruby_xml_html_parser_options.h" #include "ruby_xml_html_parser_context.h" #include "ruby_xml_reader.h" #include "ruby_xml_writer.h" #include "ruby_xml_sax2_handler.h" #include "ruby_xml_sax_parser.h" #include "ruby_xml_writer.h" #include "ruby_xml_xinclude.h" #include "ruby_xml_xpath.h" #include "ruby_xml_xpath_expression.h" #include "ruby_xml_xpath_context.h" #include "ruby_xml_xpath_object.h" #include "ruby_xml_xpointer.h" #include "ruby_xml_input_cbg.h" #include "ruby_xml_dtd.h" #include "ruby_xml_schema.h" #include "ruby_xml_relaxng.h" extern VALUE mLibXML; #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_sax_parser.c0000644000004100000410000000624013760147770022354 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include "ruby_libxml.h" #include "ruby_xml_sax_parser.h" /* * Document-class: LibXML::XML::SaxParser * * XML::SaxParser provides a callback based API for parsing documents, * in contrast to XML::Parser's tree based API and XML::Reader's stream * based API. * * The XML::SaxParser API is fairly complex, not well standardized, * and does not directly support validation making entity, namespace and * base processing relatively hard. * * To use the XML::SaxParser, register a callback class via the * XML::SaxParser#callbacks=. It is easiest to include the * XML::SaxParser::Callbacks module in your class and override * the methods as needed. * * Basic example: * * class MyCallbacks * include XML::SaxParser::Callbacks * def on_start_element(element, attributes) * puts #Element started: #{element}" * end * end * * parser = XML::SaxParser.string(my_string) * parser.callbacks = MyCallbacks.new * parser.parse * * You can also parse strings (see XML::SaxParser.string) and * io objects (see XML::SaxParser.io). */ VALUE cXMLSaxParser; static ID CALLBACKS_ATTR; static ID CONTEXT_ATTR; /* ====== Parser =========== */ /* * call-seq: * parser.initialize(context) -> XML::Parser * * Creates a new XML::Parser from the specified * XML::Parser::Context. */ static VALUE rxml_sax_parser_initialize(int argc, VALUE *argv, VALUE self) { VALUE context = Qnil; rb_scan_args(argc, argv, "01", &context); if (context == Qnil) { rb_raise(rb_eArgError, "An instance of a XML::Parser::Context must be passed to XML::SaxParser.new"); } rb_ivar_set(self, CONTEXT_ATTR, context); return self; } /* * call-seq: * parser.parse -> (true|false) * * Parse the input XML, generating callbacks to the object * registered via the +callbacks+ attributesibute. */ static VALUE rxml_sax_parser_parse(VALUE self) { int status; VALUE context = rb_ivar_get(self, CONTEXT_ATTR); xmlParserCtxtPtr ctxt; Data_Get_Struct(context, xmlParserCtxt, ctxt); ctxt->sax2 = 1; ctxt->userData = (void*)rb_ivar_get(self, CALLBACKS_ATTR); if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler) xmlFree(ctxt->sax); ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(rxml_sax_handler)); if (ctxt->sax == NULL) rb_fatal("Not enough memory."); memcpy(ctxt->sax, &rxml_sax_handler, sizeof(rxml_sax_handler)); status = xmlParseDocument(ctxt); /* Now check the parsing result*/ if (status == -1 || !ctxt->wellFormed) { rxml_raise(&ctxt->lastError); } return Qtrue; } void rxml_init_sax_parser(void) { /* SaxParser */ cXMLSaxParser = rb_define_class_under(mXML, "SaxParser", rb_cObject); /* Atributes */ CALLBACKS_ATTR = rb_intern("@callbacks"); CONTEXT_ATTR = rb_intern("@context"); rb_define_attr(cXMLSaxParser, "callbacks", 1, 1); /* Instance Methods */ rb_define_method(cXMLSaxParser, "initialize", rxml_sax_parser_initialize, -1); rb_define_method(cXMLSaxParser, "parse", rxml_sax_parser_parse, 0); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_schema_facet.c0000644000004100000410000000232613760147770022610 0ustar www-datawww-data#include "ruby_libxml.h" #include "ruby_xml_schema_facet.h" VALUE cXMLSchemaFacet; static void rxml_schema_facet_free(xmlSchemaFacetPtr xschema_type) { xschema_type = NULL; xmlFree(xschema_type); } /* START FACET*/ static VALUE rxml_schema_facet_node(VALUE self) { xmlSchemaFacetPtr facet; Data_Get_Struct(self, xmlSchemaFacet, facet); return rxml_node_wrap(facet->node); } static VALUE rxml_schema_facet_value(VALUE self) { xmlSchemaFacetPtr facet; Data_Get_Struct(self, xmlSchemaFacet, facet); QNIL_OR_STRING(facet->value) } static VALUE rxml_schema_facet_kind(VALUE self) { xmlSchemaFacetPtr facet; Data_Get_Struct(self, xmlSchemaFacet, facet); return INT2NUM(facet->type); } VALUE rxml_wrap_schema_facet(xmlSchemaFacetPtr facet) { return Data_Wrap_Struct(cXMLSchemaFacet, NULL, rxml_schema_facet_free, facet); } void rxml_init_schema_facet(void) { cXMLSchemaFacet = rb_define_class_under(cXMLSchema, "Facet", rb_cObject); rb_define_method(cXMLSchemaFacet, "value", rxml_schema_facet_value, 0); rb_define_method(cXMLSchemaFacet, "node", rxml_schema_facet_node, 0); rb_define_method(cXMLSchemaFacet, "kind", rxml_schema_facet_kind, 0); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_schema_type.c0000644000004100000410000001360113760147770022505 0ustar www-datawww-data#include "ruby_libxml.h" #include "ruby_xml_schema_type.h" #include "ruby_xml_schema_element.h" #include "ruby_xml_schema_attribute.h" #include "ruby_xml_schema_facet.h" #define UNBOUNDED 1 << 30 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; } VALUE cXMLSchemaType; static void rxml_schema_type_free(xmlSchemaTypePtr xschema_type) { xschema_type = NULL; xmlFree(xschema_type); } VALUE rxml_wrap_schema_type(xmlSchemaTypePtr xtype) { return Data_Wrap_Struct(cXMLSchemaType, NULL, rxml_schema_type_free, xtype); } static VALUE rxml_schema_type_namespace(VALUE self) { xmlSchemaTypePtr xtype; Data_Get_Struct(self, xmlSchemaType, xtype); QNIL_OR_STRING(xtype->targetNamespace) } static VALUE rxml_schema_type_name(VALUE self) { xmlSchemaTypePtr xtype; Data_Get_Struct(self, xmlSchemaType, xtype); QNIL_OR_STRING(xtype->name) } static VALUE rxml_schema_type_base(VALUE self) { xmlSchemaTypePtr xtype; Data_Get_Struct(self, xmlSchemaType, xtype); return Data_Wrap_Struct(cXMLSchemaType, NULL, rxml_schema_type_free, xtype->baseType); } static VALUE rxml_schema_type_facets(VALUE self) { xmlSchemaTypePtr xtype; xmlSchemaFacetPtr xfacet; VALUE result = rb_ary_new(); VALUE facet; Data_Get_Struct(self, xmlSchemaType, xtype); xfacet = xtype->facets; while (xfacet != NULL) { facet = rxml_wrap_schema_facet((xmlSchemaFacetPtr)xfacet); rb_ary_push(result, facet); xfacet = xfacet->next; } return result; } static VALUE rxml_schema_type_node(VALUE self) { xmlSchemaTypePtr xtype; Data_Get_Struct(self, xmlSchemaType, xtype); if(xtype->node != NULL) return rxml_node_wrap(xtype->node); else return Qnil; } static VALUE rxml_schema_type_kind(VALUE self) { xmlSchemaTypePtr xtype; Data_Get_Struct(self, xmlSchemaType, xtype); return INT2NUM(xtype->type); } static VALUE rxml_schema_type_annot(VALUE self) { VALUE result = Qnil; xmlSchemaTypePtr xtype; Data_Get_Struct(self, xmlSchemaType, xtype); if(xtype != NULL && xtype->annot != NULL && xtype->annot->content != NULL) { xmlChar *content = xmlNodeGetContent(xtype->annot->content); if (content) { result = rxml_new_cstr(content, NULL); xmlFree(content); } } return result; } static void rxmlSchemaCollectElements(xmlSchemaParticlePtr xparticle, VALUE hash) { VALUE element; xmlSchemaTreeItemPtr xterm; if (xparticle == NULL) return; xterm = xparticle->children; if (xterm != NULL) { switch (xterm->type) { case XML_SCHEMA_TYPE_ELEMENT: element = rxml_wrap_schema_element((xmlSchemaElementPtr)xterm); rb_iv_set(element, "@min", INT2NUM(xparticle->minOccurs)); if (xparticle->maxOccurs >= UNBOUNDED) rb_iv_set(element, "@max", rb_const_get(rb_path2class("Float"), rb_intern("INFINITY"))); else rb_iv_set(element, "@max", INT2NUM(xparticle->maxOccurs)); if (xparticle->annot != NULL) { xmlChar *content = xmlNodeGetContent(xparticle->annot->content); if (content != NULL) { rb_iv_set(element, "@annotation", rb_str_new2((const char *) content)); xmlFree(content); } } rb_hash_aset(hash, rb_str_new2((const char *) ((xmlSchemaElementPtr)xterm)->name), element); break; case XML_SCHEMA_TYPE_SEQUENCE: break; case XML_SCHEMA_TYPE_CHOICE: break; case XML_SCHEMA_TYPE_ALL: break; case XML_SCHEMA_TYPE_ANY: break; default: return; } } if (xterm && ((xterm->type == XML_SCHEMA_TYPE_SEQUENCE) || (xterm->type == XML_SCHEMA_TYPE_CHOICE) || (xterm->type == XML_SCHEMA_TYPE_ALL)) && (xterm->children != NULL)) { rxmlSchemaCollectElements((xmlSchemaParticlePtr)xterm->children, hash); } if (xparticle->next != NULL) { rxmlSchemaCollectElements((xmlSchemaParticlePtr)xparticle->next, hash); } } static VALUE rxml_schema_type_elements(VALUE self) { VALUE result = rb_hash_new(); xmlSchemaTypePtr xtype; Data_Get_Struct(self, xmlSchemaType, xtype); rxmlSchemaCollectElements((xmlSchemaParticlePtr) xtype->subtypes, result); return result; } static VALUE rxml_schema_type_attributes(VALUE self) { VALUE result = rb_ary_new(); xmlSchemaTypePtr xtype; xmlSchemaAttributeUsePtr xuse; xmlSchemaItemListPtr xuses; int i; Data_Get_Struct(self, xmlSchemaType, xtype); xuses = xtype->attrUses; if (xuses != NULL) { for (i = 0; i < xuses->nbItems; i++) { xuse = (xmlSchemaAttributeUsePtr)xuses->items[i]; rb_ary_push(result, rxml_wrap_schema_attribute(xuse)); } } return result; } void rxml_init_schema_type(void) { /* Add in infinity support for ruby 1.8.7 */ #if !defined(RUBY_VM) && defined(INFINITY) ID infinityId = rb_intern("INFINITY"); if (rb_const_defined(rb_cFloat, infinityId) == Qfalse) rb_define_const(rb_cFloat, "INFINITY", rb_float_new(INFINITY)); #endif cXMLSchemaType = rb_define_class_under(cXMLSchema, "Type", rb_cObject); rb_define_method(cXMLSchemaType, "namespace", rxml_schema_type_namespace, 0); rb_define_method(cXMLSchemaType, "name", rxml_schema_type_name, 0); rb_define_method(cXMLSchemaType, "elements", rxml_schema_type_elements, 0); rb_define_method(cXMLSchemaType, "attributes", rxml_schema_type_attributes, 0); rb_define_method(cXMLSchemaType, "base", rxml_schema_type_base, 0); rb_define_method(cXMLSchemaType, "kind", rxml_schema_type_kind, 0); rb_define_method(cXMLSchemaType, "node", rxml_schema_type_node, 0); rb_define_method(cXMLSchemaType, "facets", rxml_schema_type_facets, 0); rb_define_method(cXMLSchemaType, "annotation", rxml_schema_type_annot, 0); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_html_parser_context.h0000644000004100000410000000037213760147770024276 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_HTML_PARSER_CONTEXT__ #define __RXML_HTML_PARSER_CONTEXT__ extern VALUE cXMLHtmlParserContext; void rxml_init_html_parser_context(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_namespace.c0000644000004100000410000001043413760147770022141 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include "ruby_libxml.h" #include "ruby_xml_namespace.h" VALUE cXMLNamespace; /* Document-class: LibXML::XML::Namespace * * The Namespace class represents an XML namespace. * To add a namespace to a node, create a new instance * of this class. Note that this does *not* assign the * node to the namespace. To do that see the * XML::Namespaces#namespace method. * * Usage: * * node = XML::Node.new('') * XML::Namespace.new(node, 'soap', 'http://schemas.xmlsoap.org/soap/envelope/') * assert_equal("", node.to_s) * assert_nil(node.namespaces.namespace) */ /* Namespaces are owned and freed by their nodes. Thus, its easier for the ruby bindings to not manage attribute memory management. */ static VALUE rxml_namespace_alloc(VALUE klass) { return Data_Wrap_Struct(klass, NULL, NULL, NULL); } VALUE rxml_namespace_wrap(xmlNsPtr xns) { return Data_Wrap_Struct(cXMLNamespace, NULL, NULL, xns); } /* * call-seq: * initialize(node, "prefix", "href") -> XML::Namespace * * Create a new namespace and adds it to the specified node. * Note this does *not* assign the node to the namespace. * To do that see the XML::Namespaces#namespace method. */ static VALUE rxml_namespace_initialize(VALUE self, VALUE node, VALUE prefix, VALUE href) { xmlNodePtr xnode; xmlChar *xmlPrefix; xmlNsPtr xns; Check_Type(node, T_DATA); Data_Get_Struct(node, xmlNode, xnode); /* Prefix can be null - that means its the default namespace */ xmlPrefix = NIL_P(prefix) ? NULL : (xmlChar *)StringValuePtr(prefix); xns = xmlNewNs(xnode, (xmlChar*) StringValuePtr(href), xmlPrefix); if (!xns) rxml_raise(&xmlLastError); DATA_PTR(self) = xns; return self; } /* * call-seq: * ns.href -> "href" * * Usage: * * doc = XML::Document.string('') * ns = doc.root.namespaces.find_by_href('http://schemas.xmlsoap.org/soap/envelope/') * assert_equal('http://schemas.xmlsoap.org/soap/envelope/', ns.href) */ static VALUE rxml_namespace_href_get(VALUE self) { xmlNsPtr xns; Data_Get_Struct(self, xmlNs, xns); if (xns->href == NULL) return Qnil; else return rxml_new_cstr( xns->href, NULL); } /* * call-seq: * ns.node_type -> num * * Obtain this namespace's type identifier. */ static VALUE rxml_namespace_node_type(VALUE self) { xmlNsPtr xns; Data_Get_Struct(self, xmlNs, xns); return INT2NUM(xns->type); } /* * call-seq: * ns.prefix -> "prefix" * * Obtain the namespace's prefix. * * Usage: * * doc = XML::Document.string('') * ns = doc.root.namespaces.find_by_href('http://schemas.xmlsoap.org/soap/envelope/') * assert_equal('soap', ns.prefix) */ static VALUE rxml_namespace_prefix_get(VALUE self) { xmlNsPtr xns; Data_Get_Struct(self, xmlNs, xns); if (xns->prefix == NULL) return Qnil; else return rxml_new_cstr( xns->prefix, NULL); } /* * call-seq: * ns.next -> XML::Namespace * * Obtain the next namespace. * * Usage: * * doc = XML::Document.string('') * ns = doc.root.namespaces.find_by_href('http://schemas.xmlsoap.org/soap/envelope/') * assert_nil(ns.next) */ static VALUE rxml_namespace_next(VALUE self) { xmlNsPtr xns; Data_Get_Struct(self, xmlNs, xns); if (xns == NULL || xns->next == NULL) return (Qnil); else return rxml_namespace_wrap(xns->next); } void rxml_init_namespace(void) { cXMLNamespace = rb_define_class_under(mXML, "Namespace", rb_cObject); rb_define_alloc_func(cXMLNamespace, rxml_namespace_alloc); rb_define_method(cXMLNamespace, "initialize", rxml_namespace_initialize, 3); rb_define_method(cXMLNamespace, "href", rxml_namespace_href_get, 0); rb_define_method(cXMLNamespace, "next", rxml_namespace_next, 0); rb_define_method(cXMLNamespace, "node_type", rxml_namespace_node_type, 0); rb_define_method(cXMLNamespace, "prefix", rxml_namespace_prefix_get, 0); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_parser.c0000644000004100000410000000476213760147770021510 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include #include "ruby_libxml.h" /* * Document-class: LibXML::XML::Parser * * The XML::Parser provides a tree based API for processing * xml documents, in contract to XML::Reader's stream * based api and XML::SaxParser callback based API. * * As a result, parsing a document creates an in-memory document object * that consist of any number of XML::Node instances. This is simple * and powerful model, but has the major limitation that the size of * the document that can be processed is limited by the amount of * memory available. In such cases, it is better to use the XML::Reader. * * Using the parser is simple: * * parser = XML::Parser.file('my_file') * doc = parser.parse * * You can also parse documents (see XML::Parser.document), * strings (see XML::Parser.string) and io objects (see * XML::Parser.io). */ VALUE cXMLParser; static ID CONTEXT_ATTR; /* * call-seq: * parser.initialize(context) -> XML::Parser * * Creates a new XML::Parser from the specified * XML::Parser::Context. */ static VALUE rxml_parser_initialize(int argc, VALUE *argv, VALUE self) { VALUE context = Qnil; rb_scan_args(argc, argv, "01", &context); if (context == Qnil) { rb_raise(rb_eArgError, "An instance of a XML::Parser::Context must be passed to XML::Parser.new"); } rb_ivar_set(self, CONTEXT_ATTR, context); return self; } /* * call-seq: * parser.parse -> XML::Document * * Parse the input XML and create an XML::Document with * it's content. If an error occurs, XML::Parser::ParseError * is thrown. */ static VALUE rxml_parser_parse(VALUE self) { xmlParserCtxtPtr ctxt; VALUE context = rb_ivar_get(self, CONTEXT_ATTR); Data_Get_Struct(context, xmlParserCtxt, ctxt); if ((xmlParseDocument(ctxt) == -1 || !ctxt->wellFormed) && ! ctxt->recovery) { rxml_raise(&ctxt->lastError); } rb_funcall(context, rb_intern("close"), 0); return rxml_document_wrap(ctxt->myDoc); } void rxml_init_parser(void) { cXMLParser = rb_define_class_under(mXML, "Parser", rb_cObject); /* Atributes */ CONTEXT_ATTR = rb_intern("@context"); rb_define_attr(cXMLParser, "input", 1, 0); rb_define_attr(cXMLParser, "context", 1, 0); /* Instance Methods */ rb_define_method(cXMLParser, "initialize", rxml_parser_initialize, -1); rb_define_method(cXMLParser, "parse", rxml_parser_parse, 0); } libxml-ruby-3.2.1/ext/libxml/extconf.rb0000644000004100000410000000311013760147770020104 0ustar www-datawww-data#!/usr/bin/env ruby require 'mkmf' def crash(str) printf(" extconf failure: %s\n", str) exit 1 end xc = with_config('xml2-config') if xc cflags = `#{xc} --cflags`.chomp if $? != 0 cflags = nil else libs = `#{xc} --libs`.chomp if $? != 0 libs = nil else $CFLAGS += ' ' + cflags $libs = libs + " " + $libs end end else dir_config('xml2') end found_header = find_header('libxml/xmlversion.h', '/opt/include/libxml2', '/opt/local/include/libxml2', '/usr/local/include/libxml2', '/usr/include/libxml2', '/usr/local/include') found_lib = find_library('xml2', 'xmlParseDoc', '/opt/lib', '/opt/local/lib', '/usr/local/lib', '/usr/lib') found_lib ||= find_library('libxml2', 'xmlParseDoc', '/opt/lib', '/opt/local/lib', '/usr/local/lib', '/usr/lib') if !found_header || !found_lib crash(<<~EOL) Cannot find libxml2. Install the library or try one of the following options to extconf.rb: --with-xml2-config=/path/to/xml2-config --with-xml2-dir=/path/to/libxml2 --with-xml2-lib=/path/to/libxml2/lib --with-xml2-include=/path/to/libxml2/include EOL end create_header() create_makefile('libxml_ruby') libxml-ruby-3.2.1/ext/libxml/ruby_xml_parser_context.c0000644000004100000410000006431113760147770023250 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include "ruby_libxml.h" #include "ruby_xml_parser_context.h" VALUE cXMLParserContext; static ID IO_ATTR; /* * Document-class: LibXML::XML::Parser::Context * * The XML::Parser::Context class provides in-depth control over how * a document is parsed. */ static void rxml_parser_context_free(xmlParserCtxtPtr ctxt) { xmlFreeParserCtxt(ctxt); } static VALUE rxml_parser_context_wrap(xmlParserCtxtPtr ctxt) { return Data_Wrap_Struct(cXMLParserContext, NULL, rxml_parser_context_free, ctxt); } static VALUE rxml_parser_context_alloc(VALUE klass) { xmlParserCtxtPtr ctxt = xmlNewParserCtxt(); return Data_Wrap_Struct(klass, NULL, rxml_parser_context_free, ctxt); } /* call-seq: * XML::Parser::Context.document(document) -> XML::Parser::Context * * Creates a new parser context based on the specified document. * * Parameters: * * document - An XML::Document instance. */ static VALUE rxml_parser_context_document(VALUE klass, VALUE document) { xmlParserCtxtPtr ctxt; xmlDocPtr xdoc; xmlChar *buffer; int length; if (rb_obj_is_kind_of(document, cXMLDocument) == Qfalse) rb_raise(rb_eTypeError, "Must pass an LibXML::XML::Document object"); Data_Get_Struct(document, xmlDoc, xdoc); xmlDocDumpFormatMemoryEnc(xdoc, &buffer, &length, (const char*)xdoc->encoding, 0); ctxt = xmlCreateDocParserCtxt(buffer); if (!ctxt) rxml_raise(&xmlLastError); /* This is annoying, but xmlInitParserCtxt (called indirectly above) and xmlCtxtUseOptionsInternal (called below) initialize slightly different context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */ xmlCtxtUseOptions(ctxt, rxml_libxml_default_options()); return rxml_parser_context_wrap(ctxt); } /* call-seq: * XML::Parser::Context.file(file) -> XML::Parser::Context * * Creates a new parser context based on the specified file or uri. * * Parameters: * * file - A filename or uri. */ static VALUE rxml_parser_context_file(VALUE klass, VALUE file) { xmlParserCtxtPtr ctxt = xmlCreateURLParserCtxt(StringValuePtr(file), 0); if (!ctxt) rxml_raise(&xmlLastError); /* This is annoying, but xmlInitParserCtxt (called indirectly above) and xmlCtxtUseOptionsInternal (called below) initialize slightly different context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */ xmlCtxtUseOptions(ctxt, rxml_libxml_default_options()); return rxml_parser_context_wrap(ctxt); } /* call-seq: * XML::Parser::Context.string(string) -> XML::Parser::Context * * Creates a new parser context based on the specified string. * * Parameters: * * string - A string that contains the data to parse. */ static VALUE rxml_parser_context_string(VALUE klass, VALUE string) { xmlParserCtxtPtr ctxt; Check_Type(string, T_STRING); if (RSTRING_LEN(string) == 0) rb_raise(rb_eArgError, "Must specify a string with one or more characters"); ctxt = xmlCreateMemoryParserCtxt(StringValuePtr(string), (int)RSTRING_LEN(string)); if (!ctxt) rxml_raise(&xmlLastError); /* This is annoying, but xmlInitParserCtxt (called indirectly above) and xmlCtxtUseOptionsInternal (called below) initialize slightly different context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */ xmlCtxtUseOptions(ctxt, rxml_libxml_default_options()); return rxml_parser_context_wrap(ctxt); } /* call-seq: * XML::Parser::Context.io(io) -> XML::Parser::Context * * Creates a new parser context based on the specified io object. * * Parameters: * * io - A ruby IO object. */ static VALUE rxml_parser_context_io(VALUE klass, VALUE io) { VALUE result; xmlParserCtxtPtr ctxt; xmlParserInputBufferPtr input; xmlParserInputPtr stream; if (NIL_P(io)) rb_raise(rb_eTypeError, "Must pass in an IO object"); input = xmlParserInputBufferCreateIO((xmlInputReadCallback) rxml_read_callback, NULL, (void*)io, XML_CHAR_ENCODING_NONE); ctxt = xmlNewParserCtxt(); if (!ctxt) { xmlFreeParserInputBuffer(input); rxml_raise(&xmlLastError); } /* This is annoying, but xmlInitParserCtxt (called indirectly above) and xmlCtxtUseOptionsInternal (called below) initialize slightly different context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */ xmlCtxtUseOptions(ctxt, rxml_libxml_default_options()); stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE); if (!stream) { xmlFreeParserInputBuffer(input); xmlFreeParserCtxt(ctxt); rxml_raise(&xmlLastError); } inputPush(ctxt, stream); result = rxml_parser_context_wrap(ctxt); /* Attach io object to parser so it won't get freed.*/ rb_ivar_set(result, IO_ATTR, io); return result; } /* * call-seq: * context.base_uri -> "http:://libxml.org" * * Obtain the base url for this parser context. */ static VALUE rxml_parser_context_base_uri_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->input && ctxt->input->filename) return rxml_new_cstr((const xmlChar*)ctxt->input->filename, ctxt->encoding); else return Qnil; } /* * call-seq: * context.base_uri = "http:://libxml.org" * * Sets the base url for this parser context. */ static VALUE rxml_parser_context_base_uri_set(VALUE self, VALUE url) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); Check_Type(url, T_STRING); if (ctxt->input && !ctxt->input->filename) { const char* xurl = StringValuePtr(url); ctxt->input->filename = (const char*)xmlStrdup((const xmlChar*)xurl); } return self; } /* * call-seq: * context.close -> nil * * Closes the underlying input streams. This is useful when parsing a large amount of * files and you want to close the files without relying on Ruby's garbage collector * to run. */ static VALUE rxml_parser_context_close(VALUE self) { xmlParserCtxtPtr ctxt; xmlParserInputPtr xinput; Data_Get_Struct(self, xmlParserCtxt, ctxt); while ((xinput = inputPop(ctxt)) != NULL) { xmlFreeInputStream(xinput); } return Qnil; } /* * call-seq: * context.data_directory -> "dir" * * Obtain the data directory associated with this context. */ static VALUE rxml_parser_context_data_directory_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->directory == NULL) return (Qnil); else return (rxml_new_cstr((const xmlChar*)ctxt->directory, ctxt->encoding)); } /* * call-seq: * context.depth -> num * * Obtain the depth of this context. */ static VALUE rxml_parser_context_depth_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); return (INT2NUM(ctxt->depth)); } /* * call-seq: * context.disable_cdata? -> (true|false) * * Determine whether CDATA nodes will be created in this context. */ static VALUE rxml_parser_context_disable_cdata_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); /* LibXML controls this internally with the default SAX handler. */ if (ctxt->sax && ctxt->sax->cdataBlock) return (Qfalse); else return (Qtrue); } /* * call-seq: * context.disable_cdata = (true|false) * * Control whether CDATA nodes will be created in this context. */ static VALUE rxml_parser_context_disable_cdata_set(VALUE self, VALUE value) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->sax == NULL) rb_raise(rb_eRuntimeError, "Sax handler is not yet set"); /* LibXML controls this internally with the default SAX handler. */ if (value) ctxt->sax->cdataBlock = NULL; else ctxt->sax->cdataBlock = xmlDefaultSAXHandler.cdataBlock; return value; } /* * call-seq: * context.disable_sax? -> (true|false) * * Determine whether SAX-based processing is disabled * in this context. */ static VALUE rxml_parser_context_disable_sax_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->disableSAX) return (Qtrue); else return (Qfalse); } /* * call-seq: * context.docbook? -> (true|false) * * Determine whether this is a docbook context. */ static VALUE rxml_parser_context_docbook_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->html == 2) // TODO check this return (Qtrue); else return (Qfalse); } /* * call-seq: * context.encoding -> XML::Encoding::UTF_8 * * Obtain the character encoding identifier used in * this context. */ static VALUE rxml_parser_context_encoding_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); return INT2NUM(xmlParseCharEncoding((const char*)ctxt->encoding)); } /* * call-seq: * context.encoding = XML::Encoding::UTF_8 * * Sets the character encoding for this context. */ static VALUE rxml_parser_context_encoding_set(VALUE self, VALUE encoding) { xmlParserCtxtPtr ctxt; int result; const char* xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(encoding)); xmlCharEncodingHandlerPtr hdlr = xmlFindCharEncodingHandler(xencoding); if (!hdlr) rb_raise(rb_eArgError, "Unknown encoding: %i", NUM2INT(encoding)); Data_Get_Struct(self, xmlParserCtxt, ctxt); result = xmlSwitchToEncoding(ctxt, hdlr); if (result != 0) rxml_raise(&xmlLastError); if (ctxt->encoding != NULL) xmlFree((xmlChar *) ctxt->encoding); ctxt->encoding = xmlStrdup((const xmlChar *) xencoding); return self; } /* * call-seq: * context.errno -> num * * Obtain the last-error number in this context. */ static VALUE rxml_parser_context_errno_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); return (INT2NUM(ctxt->errNo)); } /* * call-seq: * context.html? -> (true|false) * * Determine whether this is an html context. */ static VALUE rxml_parser_context_html_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->html == 1) return (Qtrue); else return (Qfalse); } /* * call-seq: * context.max_num_streams -> num * * Obtain the limit on the number of IO streams opened in * this context. */ static VALUE rxml_parser_context_io_max_num_streams_get(VALUE self) { // TODO alias to max_streams and dep this? xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); return (INT2NUM(ctxt->inputMax)); } /* * call-seq: * context.num_streams -> "dir" * * Obtain the actual number of IO streams in this * context. */ static VALUE rxml_parser_context_io_num_streams_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); return (INT2NUM(ctxt->inputNr)); } /* * call-seq: * context.keep_blanks? -> (true|false) * * Determine whether parsers in this context retain * whitespace. */ static VALUE rxml_parser_context_keep_blanks_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->keepBlanks) return (Qtrue); else return (Qfalse); } /* * call-seq: * context.name_depth -> num * * Obtain the name depth for this context. */ static VALUE rxml_parser_context_name_depth_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); return (INT2NUM(ctxt->nameNr)); } /* * call-seq: * context.name_depth_max -> num * * Obtain the maximum name depth for this context. */ static VALUE rxml_parser_context_name_depth_max_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); return (INT2NUM(ctxt->nameMax)); } /* * call-seq: * context.name_node -> "name" * * Obtain the name node for this context. */ static VALUE rxml_parser_context_name_node_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->name == NULL) return (Qnil); else return (rxml_new_cstr( ctxt->name, ctxt->encoding)); } /* * call-seq: * context.name_tab -> ["name", ..., "name"] * * Obtain the name table for this context. */ static VALUE rxml_parser_context_name_tab_get(VALUE self) { int i; xmlParserCtxtPtr ctxt; VALUE tab_ary; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->nameTab == NULL) return (Qnil); tab_ary = rb_ary_new(); for (i = (ctxt->nameNr - 1); i >= 0; i--) { if (ctxt->nameTab[i] == NULL) continue; else rb_ary_push(tab_ary, rxml_new_cstr( ctxt->nameTab[i], ctxt->encoding)); } return (tab_ary); } /* * call-seq: * context.node_depth -> num * * Obtain the node depth for this context. */ static VALUE rxml_parser_context_node_depth_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); return (INT2NUM(ctxt->nodeNr)); } /* * call-seq: * context.node -> node * * Obtain the root node of this context. */ static VALUE rxml_parser_context_node_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->node == NULL) return (Qnil); else return (rxml_node_wrap(ctxt->node)); } /* * call-seq: * context.node_depth_max -> num * * Obtain the maximum node depth for this context. */ static VALUE rxml_parser_context_node_depth_max_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); return (INT2NUM(ctxt->nodeMax)); } /* * call-seq: * context.num_chars -> num * * Obtain the number of characters in this context. */ static VALUE rxml_parser_context_num_chars_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); return (LONG2NUM(ctxt->nbChars)); } /* * call-seq: * context.options > XML::Parser::Options::NOENT * * Returns the parser options for this context. Multiple * options can be combined by using Bitwise OR (|). */ static VALUE rxml_parser_context_options_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); return INT2NUM(ctxt->options); } /* * call-seq: * context.options = XML::Parser::Options::NOENT | XML::Parser::Options::NOCDATA * * Provides control over the execution of a parser. Valid values * are the constants defined on XML::Parser::Options. Multiple * options can be combined by using Bitwise OR (|). */ static VALUE rxml_parser_context_options_set(VALUE self, VALUE options) { xmlParserCtxtPtr ctxt; Check_Type(options, T_FIXNUM); Data_Get_Struct(self, xmlParserCtxt, ctxt); xmlCtxtUseOptions(ctxt, NUM2INT(options)); return self; } /* * call-seq: * context.recovery? -> (true|false) * * Determine whether recovery mode is enabled in this * context. */ static VALUE rxml_parser_context_recovery_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->recovery) return (Qtrue); else return (Qfalse); } /* * call-seq: * context.recovery = true|false * * Control whether recovery mode is enabled in this * context. */ static VALUE rxml_parser_context_recovery_set(VALUE self, VALUE value) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (value == Qfalse) { ctxt->recovery = 0; return (Qfalse); } else { ctxt->recovery = 1; return (Qtrue); } } /* * call-seq: * context.replace_entities? -> (true|false) * * Determine whether external entity replacement is enabled in this * context. */ static VALUE rxml_parser_context_replace_entities_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->replaceEntities) return (Qtrue); else return (Qfalse); } /* * call-seq: * context.replace_entities = true|false * * Control whether external entity replacement is enabled in this * context. */ static VALUE rxml_parser_context_replace_entities_set(VALUE self, VALUE value) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (value == Qfalse) { ctxt->replaceEntities = 0; return (Qfalse); } else { ctxt->replaceEntities = 1; return (Qtrue); } } /* * call-seq: * context.space_depth -> num * * Obtain the space depth for this context. */ static VALUE rxml_parser_context_space_depth_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); return (INT2NUM(ctxt->spaceNr)); } /* * call-seq: * context.space_depth -> num * * Obtain the maximum space depth for this context. */ static VALUE rxml_parser_context_space_depth_max_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); return (INT2NUM(ctxt->spaceMax)); } /* * call-seq: * context.subset_external? -> (true|false) * * Determine whether this context is a subset of an * external context. */ static VALUE rxml_parser_context_subset_external_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->inSubset == 2) return (Qtrue); else return (Qfalse); } /* * call-seq: * context.subset_internal? -> (true|false) * * Determine whether this context is a subset of an * internal context. */ static VALUE rxml_parser_context_subset_internal_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->inSubset == 1) return (Qtrue); else return (Qfalse); } /* * call-seq: * context.subset_internal_name -> "name" * * Obtain this context's subset name (valid only if * either of subset_external? or subset_internal? * is true). */ static VALUE rxml_parser_context_subset_name_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->intSubName == NULL) return (Qnil); else return (rxml_new_cstr(ctxt->intSubName, ctxt->encoding)); } /* * call-seq: * context.subset_external_uri -> "uri" * * Obtain this context's external subset URI. (valid only if * either of subset_external? or subset_internal? * is true). */ static VALUE rxml_parser_context_subset_external_uri_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->extSubURI == NULL) return (Qnil); else return (rxml_new_cstr( ctxt->extSubURI, ctxt->encoding)); } /* * call-seq: * context.subset_external_system_id -> "system_id" * * Obtain this context's external subset system identifier. * (valid only if either of subset_external? or subset_internal? * is true). */ static VALUE rxml_parser_context_subset_external_system_id_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->extSubSystem == NULL) return (Qnil); else return (rxml_new_cstr( ctxt->extSubSystem, ctxt->encoding)); } /* * call-seq: * context.standalone? -> (true|false) * * Determine whether this is a standalone context. */ static VALUE rxml_parser_context_standalone_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->standalone) return (Qtrue); else return (Qfalse); } /* * call-seq: * context.stats? -> (true|false) * * Determine whether this context maintains statistics. */ static VALUE rxml_parser_context_stats_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->record_info) return (Qtrue); else return (Qfalse); } /* * call-seq: * context.valid? -> (true|false) * * Determine whether this context is valid. */ static VALUE rxml_parser_context_valid_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->valid) return (Qtrue); else return (Qfalse); } /* * call-seq: * context.validate? -> (true|false) * * Determine whether validation is enabled in this context. */ static VALUE rxml_parser_context_validate_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->validate) return (Qtrue); else return (Qfalse); } /* * call-seq: * context.version -> "version" * * Obtain this context's version identifier. */ static VALUE rxml_parser_context_version_get(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->version == NULL) return (Qnil); else return (rxml_new_cstr( ctxt->version, ctxt->encoding)); } /* * call-seq: * context.well_formed? -> (true|false) * * Determine whether this context contains well-formed XML. */ static VALUE rxml_parser_context_well_formed_q(VALUE self) { xmlParserCtxtPtr ctxt; Data_Get_Struct(self, xmlParserCtxt, ctxt); if (ctxt->wellFormed) return (Qtrue); else return (Qfalse); } void rxml_init_parser_context(void) { IO_ATTR = ID2SYM(rb_intern("@io")); cXMLParserContext = rb_define_class_under(cXMLParser, "Context", rb_cObject); rb_define_alloc_func(cXMLParserContext, rxml_parser_context_alloc); rb_define_singleton_method(cXMLParserContext, "document", rxml_parser_context_document, 1); rb_define_singleton_method(cXMLParserContext, "file", rxml_parser_context_file, 1); rb_define_singleton_method(cXMLParserContext, "io", rxml_parser_context_io, 1); rb_define_singleton_method(cXMLParserContext, "string", rxml_parser_context_string, 1); rb_define_method(cXMLParserContext, "base_uri", rxml_parser_context_base_uri_get, 0); rb_define_method(cXMLParserContext, "base_uri=", rxml_parser_context_base_uri_set, 1); rb_define_method(cXMLParserContext, "close", rxml_parser_context_close, 0); rb_define_method(cXMLParserContext, "data_directory", rxml_parser_context_data_directory_get, 0); rb_define_method(cXMLParserContext, "depth", rxml_parser_context_depth_get, 0); rb_define_method(cXMLParserContext, "disable_cdata?", rxml_parser_context_disable_cdata_q, 0); rb_define_method(cXMLParserContext, "disable_cdata=", rxml_parser_context_disable_cdata_set, 1); rb_define_method(cXMLParserContext, "disable_sax?", rxml_parser_context_disable_sax_q, 0); rb_define_method(cXMLParserContext, "docbook?", rxml_parser_context_docbook_q, 0); rb_define_method(cXMLParserContext, "encoding", rxml_parser_context_encoding_get, 0); rb_define_method(cXMLParserContext, "encoding=", rxml_parser_context_encoding_set, 1); rb_define_method(cXMLParserContext, "errno", rxml_parser_context_errno_get, 0); rb_define_method(cXMLParserContext, "html?", rxml_parser_context_html_q, 0); rb_define_method(cXMLParserContext, "io_max_num_streams", rxml_parser_context_io_max_num_streams_get, 0); rb_define_method(cXMLParserContext, "io_num_streams", rxml_parser_context_io_num_streams_get, 0); rb_define_method(cXMLParserContext, "keep_blanks?", rxml_parser_context_keep_blanks_q, 0); rb_define_method(cXMLParserContext, "name_node", rxml_parser_context_name_node_get, 0); rb_define_method(cXMLParserContext, "name_depth", rxml_parser_context_name_depth_get, 0); rb_define_method(cXMLParserContext, "name_depth_max", rxml_parser_context_name_depth_max_get, 0); rb_define_method(cXMLParserContext, "name_tab", rxml_parser_context_name_tab_get, 0); rb_define_method(cXMLParserContext, "node", rxml_parser_context_node_get, 0); rb_define_method(cXMLParserContext, "node_depth", rxml_parser_context_node_depth_get, 0); rb_define_method(cXMLParserContext, "node_depth_max", rxml_parser_context_node_depth_max_get, 0); rb_define_method(cXMLParserContext, "num_chars", rxml_parser_context_num_chars_get, 0); rb_define_method(cXMLParserContext, "options", rxml_parser_context_options_get, 0); rb_define_method(cXMLParserContext, "options=", rxml_parser_context_options_set, 1); rb_define_method(cXMLParserContext, "recovery?", rxml_parser_context_recovery_q, 0); rb_define_method(cXMLParserContext, "recovery=", rxml_parser_context_recovery_set, 1); rb_define_method(cXMLParserContext, "replace_entities?", rxml_parser_context_replace_entities_q, 0); rb_define_method(cXMLParserContext, "replace_entities=", rxml_parser_context_replace_entities_set, 1); rb_define_method(cXMLParserContext, "space_depth", rxml_parser_context_space_depth_get, 0); rb_define_method(cXMLParserContext, "space_depth_max", rxml_parser_context_space_depth_max_get, 0); rb_define_method(cXMLParserContext, "subset_external?", rxml_parser_context_subset_external_q, 0); rb_define_method(cXMLParserContext, "subset_external_system_id", rxml_parser_context_subset_external_system_id_get, 0); rb_define_method(cXMLParserContext, "subset_external_uri", rxml_parser_context_subset_external_uri_get, 0); rb_define_method(cXMLParserContext, "subset_internal?", rxml_parser_context_subset_internal_q, 0); rb_define_method(cXMLParserContext, "subset_internal_name", rxml_parser_context_subset_name_get, 0); rb_define_method(cXMLParserContext, "stats?", rxml_parser_context_stats_q, 0); rb_define_method(cXMLParserContext, "standalone?", rxml_parser_context_standalone_q, 0); rb_define_method(cXMLParserContext, "valid", rxml_parser_context_valid_q, 0); rb_define_method(cXMLParserContext, "validate?", rxml_parser_context_validate_q, 0); rb_define_method(cXMLParserContext, "version", rxml_parser_context_version_get, 0); rb_define_method(cXMLParserContext, "well_formed?", rxml_parser_context_well_formed_q, 0); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_sax2_handler.h0000644000004100000410000000035013760147770022560 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_SAX2_HANDLER__ #define __RXML_SAX2_HANDLER__ extern xmlSAXHandler rxml_sax_handler; void rxml_init_sax2_handler(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_xpath_object.c0000644000004100000410000002242013760147770022655 0ustar www-datawww-data#include "ruby_libxml.h" /* * Document-class: LibXML::XML::XPath::Object * * A collection of nodes returned from the evaluation of an XML::XPath * or XML::XPointer expression. */ VALUE cXMLXPathObject; /* Memory management of xpath results is tricky. If a nodeset is returned, it generally consists of pointers to nodes in the original document. However, namespace nodes are handled differently - libxml creates copies of them instead. Thus, when an xmlXPathObjectPtr is freed, libxml iterates over the results to find the copied namespace nodes to free them. This causes problems for the bindings because the underlying document may be freed before the xmlXPathObjectPtr instance. This might seem counterintuitive since the xmlXPathObjectPtr marks the document. However, once both objects go out of scope, the order of their destruction is random. To deal with this, the wrapper code searches for the namespace nodes and wraps them in Ruby objects. When the Ruby objects go out of scope then the namespace nodes are freed. */ static void rxml_xpath_object_free(rxml_xpath_object *rxpop) { /* We positively, absolutely cannot let libxml iterate over the nodeTab since if the underlying document has been freed the majority of entries are invalid, resulting in segmentation faults.*/ if (rxpop->xpop->nodesetval && rxpop->xpop->nodesetval->nodeTab) { xmlFree(rxpop->xpop->nodesetval->nodeTab); rxpop->xpop->nodesetval->nodeTab = NULL; } xmlXPathFreeObject(rxpop->xpop); xfree(rxpop); } /* Custom free function for copied namespace nodes */ static void rxml_xpath_namespace_free(xmlNsPtr xns) { xmlFreeNs(xns); } static void rxml_xpath_object_mark(rxml_xpath_object *rxpop) { VALUE doc = (VALUE)rxpop->xdoc->_private; rb_gc_mark(doc); rb_gc_mark(rxpop->nsnodes); } VALUE rxml_xpath_object_wrap(xmlDocPtr xdoc, xmlXPathObjectPtr xpop) { int i; rxml_xpath_object *rxpop = ALLOC(rxml_xpath_object); /* Make sure Ruby's GC can find the array in the stack */ VALUE nsnodes = rb_ary_new(); rxpop->xdoc =xdoc; rxpop->xpop = xpop; /* Find all the extra namespace nodes and wrap them. */ if (xpop->nodesetval && xpop->nodesetval->nodeNr) { for (i = 0; i < xpop->nodesetval->nodeNr; i++) { xmlNodePtr xnode = xpop->nodesetval->nodeTab[i]; if (xnode != NULL && xnode->type == XML_NAMESPACE_DECL) { VALUE ns = Qnil; xmlNsPtr xns = (xmlNsPtr)xnode; /* Get rid of libxml's -> next hack. The issue here is the rxml_namespace code assumes that ns->next refers to another namespace. */ xns->next = NULL; /* Specify a custom free function here since by default namespace nodes will not be freed */ ns = rxml_namespace_wrap((xmlNsPtr)xnode); RDATA(ns)->dfree = (RUBY_DATA_FUNC)rxml_xpath_namespace_free; rb_ary_push(nsnodes, ns); } } } rxpop->nsnodes = nsnodes; return Data_Wrap_Struct(cXMLXPathObject, rxml_xpath_object_mark, rxml_xpath_object_free, rxpop); } static VALUE rxml_xpath_object_tabref(xmlXPathObjectPtr xpop, int index) { if (index < 0) index = xpop->nodesetval->nodeNr + index; if (index < 0 || index + 1 > xpop->nodesetval->nodeNr) return Qnil; switch (xpop->nodesetval->nodeTab[index]->type) { case XML_ATTRIBUTE_NODE: return rxml_attr_wrap((xmlAttrPtr) xpop->nodesetval->nodeTab[index]); break; case XML_NAMESPACE_DECL: return rxml_namespace_wrap((xmlNsPtr)xpop->nodesetval->nodeTab[index]); break; default: return rxml_node_wrap(xpop->nodesetval->nodeTab[index]); } } /* * call-seq: * xpath_object.to_a -> [node, ..., node] * * Obtain an array of the nodes in this set. */ static VALUE rxml_xpath_object_to_a(VALUE self) { VALUE set_ary, nodeobj; rxml_xpath_object *rxpop; xmlXPathObjectPtr xpop; int i; Data_Get_Struct(self, rxml_xpath_object, rxpop); xpop = rxpop->xpop; set_ary = rb_ary_new(); if (!((xpop->nodesetval == NULL) || (xpop->nodesetval->nodeNr == 0))) { for (i = 0; i < xpop->nodesetval->nodeNr; i++) { nodeobj = rxml_xpath_object_tabref(xpop, i); rb_ary_push(set_ary, nodeobj); } } return (set_ary); } /* * call-seq: * xpath_object.empty? -> (true|false) * * Determine whether this nodeset is empty (contains no nodes). */ static VALUE rxml_xpath_object_empty_q(VALUE self) { rxml_xpath_object *rxpop; Data_Get_Struct(self, rxml_xpath_object, rxpop); if (rxpop->xpop->type != XPATH_NODESET) return Qnil; return (rxpop->xpop->nodesetval == NULL || rxpop->xpop->nodesetval->nodeNr <= 0) ? Qtrue : Qfalse; } /* * call-seq: * xpath_object.each { |node| ... } -> self * * Call the supplied block for each node in this set. */ static VALUE rxml_xpath_object_each(VALUE self) { rxml_xpath_object *rxpop; int i; if (rxml_xpath_object_empty_q(self) == Qtrue) return Qnil; Data_Get_Struct(self, rxml_xpath_object, rxpop); for (i = 0; i < rxpop->xpop->nodesetval->nodeNr; i++) { rb_yield(rxml_xpath_object_tabref(rxpop->xpop, i)); } return (self); } /* * call-seq: * xpath_object.first -> node * * Returns the first node in this node set, or nil if none exist. */ static VALUE rxml_xpath_object_first(VALUE self) { rxml_xpath_object *rxpop; if (rxml_xpath_object_empty_q(self) == Qtrue) return Qnil; Data_Get_Struct(self, rxml_xpath_object, rxpop); return rxml_xpath_object_tabref(rxpop->xpop, 0); } /* * call-seq: * xpath_object.last -> node * * Returns the last node in this node set, or nil if none exist. */ static VALUE rxml_xpath_object_last(VALUE self) { rxml_xpath_object *rxpop; if (rxml_xpath_object_empty_q(self) == Qtrue) return Qnil; Data_Get_Struct(self, rxml_xpath_object, rxpop); return rxml_xpath_object_tabref(rxpop->xpop, -1); } /* * call-seq: * xpath_object[i] -> node * * array index into set of nodes */ static VALUE rxml_xpath_object_aref(VALUE self, VALUE aref) { rxml_xpath_object *rxpop; if (rxml_xpath_object_empty_q(self) == Qtrue) return Qnil; Data_Get_Struct(self, rxml_xpath_object, rxpop); return rxml_xpath_object_tabref(rxpop->xpop, NUM2INT(aref)); } /* * call-seq: * xpath_object.length -> num * * Obtain the length of the nodesetval node list. */ static VALUE rxml_xpath_object_length(VALUE self) { rxml_xpath_object *rxpop; if (rxml_xpath_object_empty_q(self) == Qtrue) return INT2FIX(0); Data_Get_Struct(self, rxml_xpath_object, rxpop); return INT2NUM(rxpop->xpop->nodesetval->nodeNr); } /* * call-seq: * xpath_object.xpath_type -> int * * Returns the XPath type of the result object. * Possible values are defined as constants * on the XML::XPath class and include: * * * XML::XPath::UNDEFINED * * XML::XPath::NODESET * * XML::XPath::BOOLEAN * * XML::XPath::NUMBER * * XML::XPath::STRING * * XML::XPath::POINT * * XML::XPath::RANGE * * XML::XPath::LOCATIONSET * * XML::XPath::USERS * * XML::XPath::XSLT_TREE */ static VALUE rxml_xpath_object_get_type(VALUE self) { rxml_xpath_object *rxpop; Data_Get_Struct(self, rxml_xpath_object, rxpop); return INT2FIX(rxpop->xpop->type); } /* * call-seq: * xpath_object.string -> String * * Returns the original XPath expression as a string. */ static VALUE rxml_xpath_object_string(VALUE self) { rxml_xpath_object *rxpop; Data_Get_Struct(self, rxml_xpath_object, rxpop); if (rxpop->xpop->stringval == NULL) return Qnil; return rxml_new_cstr( rxpop->xpop->stringval, rxpop->xdoc->encoding); } /* * call-seq: * nodes.debug -> (true|false) * * Dump libxml debugging information to stdout. * Requires Libxml be compiled with debugging enabled. */ static VALUE rxml_xpath_object_debug(VALUE self) { #ifdef LIBXML_DEBUG_ENABLED rxml_xpath_object *rxpop; Data_Get_Struct(self, rxml_xpath_object, rxpop); xmlXPathDebugDumpObject(stdout, rxpop->xpop, 0); return Qtrue; #else rb_warn("libxml was compiled without debugging support."); return Qfalse; #endif } void rxml_init_xpath_object(void) { cXMLXPathObject = rb_define_class_under(mXPath, "Object", rb_cObject); rb_include_module(cXMLXPathObject, rb_mEnumerable); rb_define_attr(cXMLXPathObject, "context", 1, 0); rb_define_method(cXMLXPathObject, "each", rxml_xpath_object_each, 0); rb_define_method(cXMLXPathObject, "xpath_type", rxml_xpath_object_get_type, 0); rb_define_method(cXMLXPathObject, "empty?", rxml_xpath_object_empty_q, 0); rb_define_method(cXMLXPathObject, "first", rxml_xpath_object_first, 0); rb_define_method(cXMLXPathObject, "last", rxml_xpath_object_last, 0); rb_define_method(cXMLXPathObject, "length", rxml_xpath_object_length, 0); rb_define_method(cXMLXPathObject, "to_a", rxml_xpath_object_to_a, 0); rb_define_method(cXMLXPathObject, "[]", rxml_xpath_object_aref, 1); rb_define_method(cXMLXPathObject, "string", rxml_xpath_object_string, 0); rb_define_method(cXMLXPathObject, "debug", rxml_xpath_object_debug, 0); rb_define_alias(cXMLXPathObject, "size", "length"); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_xpath_expression.c0000644000004100000410000000470213760147770023611 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include "ruby_libxml.h" #include "ruby_xml_xpath.h" #include "ruby_xml_xpath_expression.h" /* * Document-class: LibXML::XML::XPath::Expression * * The XML::XPath::Expression class is used to compile * XPath expressions so they can be parsed only once * but reused multiple times. * * doc = XML::Document.string(IO.read('some xml file')) * expr = XPath::Expression.new('//first') * doc.root.each do |node| * result = node.find(expr) # many, many, many times * # ... * end */ VALUE cXMLXPathExpression; static void rxml_xpath_expression_free(xmlXPathCompExprPtr expr) { xmlXPathFreeCompExpr(expr); } static VALUE rxml_xpath_expression_alloc(VALUE klass) { return Data_Wrap_Struct(cXMLXPathExpression, NULL, rxml_xpath_expression_free, NULL); } /* call-seq: * XPath::Expression.compile(expression) -> XPath::Expression * * Compiles an XPatch expression. This improves performance * when an XPath expression is called multiple times. * * doc = XML::Document.string('
hi
') * expr = XPath::Expression.new('//first') * nodes = doc.find(expr) */ static VALUE rxml_xpath_expression_compile(VALUE klass, VALUE expression) { VALUE args[] = {expression}; return rb_class_new_instance(1, args, cXMLXPathExpression); } /* call-seq: * XPath::Expression.new(expression) -> XPath::Expression * * Compiles an XPatch expression. This improves performance * when an XPath expression is called multiple times. * * doc = XML::Document.string('
hi
') * expr = XPath::Expression.new('//first') * nodes = doc.find(expr) */ static VALUE rxml_xpath_expression_initialize(VALUE self, VALUE expression) { xmlXPathCompExprPtr compexpr = xmlXPathCompile((const xmlChar*)StringValueCStr(expression)); if (compexpr == NULL) { xmlErrorPtr xerror = xmlGetLastError(); rxml_raise(xerror); } DATA_PTR( self) = compexpr; return self; } void rxml_init_xpath_expression(void) { cXMLXPathExpression = rb_define_class_under(mXPath, "Expression", rb_cObject); rb_define_alloc_func(cXMLXPathExpression, rxml_xpath_expression_alloc); rb_define_singleton_method(cXMLXPathExpression, "compile", rxml_xpath_expression_compile, 1); rb_define_method(cXMLXPathExpression, "initialize", rxml_xpath_expression_initialize, 1); } libxml-ruby-3.2.1/ext/libxml/ruby_xml.h0000644000004100000410000000033713760147770020133 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RUBY_XML_H__ #define __RUBY_XML_H__ extern VALUE mXML; int rxml_libxml_default_options(); void rxml_init_xml(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_attr_decl.h0000644000004100000410000000046613760147770022157 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_ATTR_DECL__ #define __RXML_ATTR_DECL__ extern VALUE cXMLAttrDecl; void rxml_init_attr_decl(void); VALUE rxml_attr_decl_wrap(xmlAttributePtr xattribute); VALUE rxml_attr_decl_value_get(VALUE self); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_reader.h0000644000004100000410000000066613760147770021462 0ustar www-datawww-data/* Copyright (c) 2006 Apple Computer Inc. * Please see the LICENSE file for copyright and distribution information. */ #ifndef __RXML_READER__ #define __RXML_READER__ #include #include extern VALUE cXMLReader; void rxml_init_reader(void); /* Exported to be used by XML::Document#reader */ VALUE rxml_reader_new_walker(VALUE self, VALUE doc); #endif /* __rxml_READER__ */ libxml-ruby-3.2.1/ext/libxml/ruby_xml_namespaces.h0000644000004100000410000000032613760147770022330 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_NAMESPACES__ #define __RXML_NAMESPACES__ extern VALUE cXMLNamespaces; void rxml_init_namespaces(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_xpath_expression.h0000644000004100000410000000035713760147770023620 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_XPATH_EXPRESSION__ #define __RXML_XPATH_EXPRESSION__ extern VALUE cXMLXPathExpression; void rxml_init_xpath_expression(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_html_parser_context.c0000644000004100000410000002434613760147770024300 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include "ruby_libxml.h" #include "ruby_xml_html_parser_context.h" /* * Document-class: LibXML::XML::HTMLParser::Context * * The XML::HTMLParser::Context class provides in-depth control over how * a document is parsed. */ VALUE cXMLHtmlParserContext; static ID IO_ATTR; /* OS X 10.5 ships with libxml2 version 2.6.16 which does not expose the htmlNewParserCtxt (or htmlInitParserCtxt which it uses) method. htmlNewParserCtxt wasn't added to the libxml2 header files until 2.6.27. So the next two methods are simply copied from a newer version of libxml2 (2.7.2). */ #if LIBXML_VERSION < 20627 #define XML_CTXT_FINISH_DTD_0 0xabcd1234 static int htmlInitParserCtxt(htmlParserCtxtPtr ctxt) { htmlSAXHandler *sax; if (ctxt == NULL) return(-1); memset(ctxt, 0, sizeof(htmlParserCtxt)); ctxt->dict = xmlDictCreate(); if (ctxt->dict == NULL) { rb_raise(rb_eNoMemError, "htmlInitParserCtxt: out of memory\n"); return(-1); } sax = (htmlSAXHandler *) xmlMalloc(sizeof(htmlSAXHandler)); if (sax == NULL) { rb_raise(rb_eNoMemError, "htmlInitParserCtxt: out of memory\n"); return(-1); } else memset(sax, 0, sizeof(htmlSAXHandler)); ctxt->inputTab = (htmlParserInputPtr *) xmlMalloc(5 * sizeof(htmlParserInputPtr)); if (ctxt->inputTab == NULL) { rb_raise(rb_eNoMemError, "htmlInitParserCtxt: out of memory\n"); ctxt->inputNr = 0; ctxt->inputMax = 0; ctxt->input = NULL; return(-1); } ctxt->inputNr = 0; ctxt->inputMax = 5; ctxt->input = NULL; ctxt->version = NULL; ctxt->encoding = NULL; ctxt->standalone = -1; ctxt->instate = XML_PARSER_START; ctxt->nodeTab = (htmlNodePtr *) xmlMalloc(10 * sizeof(htmlNodePtr)); if (ctxt->nodeTab == NULL) { rb_raise(rb_eNoMemError, "htmlInitParserCtxt: out of memory\n"); ctxt->nodeNr = 0; ctxt->nodeMax = 0; ctxt->node = NULL; ctxt->inputNr = 0; ctxt->inputMax = 0; ctxt->input = NULL; return(-1); } ctxt->nodeNr = 0; ctxt->nodeMax = 10; ctxt->node = NULL; ctxt->nameTab = (const xmlChar **) xmlMalloc(10 * sizeof(xmlChar *)); if (ctxt->nameTab == NULL) { rb_raise(rb_eNoMemError, "htmlInitParserCtxt: out of memory\n"); ctxt->nameNr = 0; ctxt->nameMax = 10; ctxt->name = NULL; ctxt->nodeNr = 0; ctxt->nodeMax = 0; ctxt->node = NULL; ctxt->inputNr = 0; ctxt->inputMax = 0; ctxt->input = NULL; return(-1); } ctxt->nameNr = 0; ctxt->nameMax = 10; ctxt->name = NULL; if (sax == NULL) ctxt->sax = (xmlSAXHandlerPtr) &htmlDefaultSAXHandler; else { ctxt->sax = sax; memcpy(sax, &htmlDefaultSAXHandler, sizeof(xmlSAXHandlerV1)); } ctxt->userData = ctxt; ctxt->myDoc = NULL; ctxt->wellFormed = 1; ctxt->replaceEntities = 0; ctxt->linenumbers = xmlLineNumbersDefaultValue; ctxt->html = 1; ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0; ctxt->vctxt.userData = ctxt; ctxt->vctxt.error = xmlParserValidityError; ctxt->vctxt.warning = xmlParserValidityWarning; ctxt->record_info = 0; ctxt->validate = 0; ctxt->nbChars = 0; ctxt->checkIndex = 0; ctxt->catalogs = NULL; xmlInitNodeInfoSeq(&ctxt->node_seq); return(0); } static htmlParserCtxtPtr htmlNewParserCtxt(void) { xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt)); if (ctxt == NULL) { rb_raise(rb_eNoMemError, "NewParserCtxt: out of memory\n"); return(NULL); } memset(ctxt, 0, sizeof(xmlParserCtxt)); if (htmlInitParserCtxt(ctxt) < 0) { htmlFreeParserCtxt(ctxt); return(NULL); } return(ctxt); } #endif static void rxml_html_parser_context_free(htmlParserCtxtPtr ctxt) { htmlFreeParserCtxt(ctxt); } static VALUE rxml_html_parser_context_wrap(htmlParserCtxtPtr ctxt) { return Data_Wrap_Struct(cXMLHtmlParserContext, NULL, rxml_html_parser_context_free, ctxt); } /* call-seq: * XML::HTMLParser::Context.file(file) -> XML::HTMLParser::Context * * Creates a new parser context based on the specified file or uri. * * Parameters: * * file - A filename or uri. */ static VALUE rxml_html_parser_context_file(VALUE klass, VALUE file) { htmlParserCtxtPtr ctxt = htmlCreateFileParserCtxt(StringValuePtr(file), NULL); if (!ctxt) rxml_raise(&xmlLastError); /* This is annoying, but xmlInitParserCtxt (called indirectly above) and xmlCtxtUseOptionsInternal (called below) initialize slightly different context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */ htmlCtxtUseOptions(ctxt, rxml_libxml_default_options()); return rxml_html_parser_context_wrap(ctxt); } /* call-seq: * XML::HTMLParser::Context.io(io) -> XML::HTMLParser::Context * * Creates a new parser context based on the specified io object. * * Parameters: * * io - A ruby IO object. */ static VALUE rxml_html_parser_context_io(VALUE klass, VALUE io) { VALUE result; htmlParserCtxtPtr ctxt; xmlParserInputBufferPtr input; xmlParserInputPtr stream; if (NIL_P(io)) rb_raise(rb_eTypeError, "Must pass in an IO object"); input = xmlParserInputBufferCreateIO((xmlInputReadCallback) rxml_read_callback, NULL, (void*)io, XML_CHAR_ENCODING_NONE); ctxt = htmlNewParserCtxt(); if (!ctxt) { xmlFreeParserInputBuffer(input); rxml_raise(&xmlLastError); } /* This is annoying, but xmlInitParserCtxt (called indirectly above) and xmlCtxtUseOptionsInternal (called below) initialize slightly different context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */ htmlCtxtUseOptions(ctxt, rxml_libxml_default_options()); stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE); if (!stream) { xmlFreeParserInputBuffer(input); xmlFreeParserCtxt(ctxt); rxml_raise(&xmlLastError); } inputPush(ctxt, stream); result = rxml_html_parser_context_wrap(ctxt); /* Attach io object to parser so it won't get freed.*/ rb_ivar_set(result, IO_ATTR, io); return result; } /* call-seq: * XML::HTMLParser::Context.string(string) -> XML::HTMLParser::Context * * Creates a new parser context based on the specified string. * * Parameters: * * string - A string that contains the data to parse. */ static VALUE rxml_html_parser_context_string(VALUE klass, VALUE string) { htmlParserCtxtPtr ctxt; Check_Type(string, T_STRING); if (RSTRING_LEN(string) == 0) rb_raise(rb_eArgError, "Must specify a string with one or more characters"); ctxt = xmlCreateMemoryParserCtxt(StringValuePtr(string), (int)RSTRING_LEN(string)); if (!ctxt) rxml_raise(&xmlLastError); /* This is annoying, but xmlInitParserCtxt (called indirectly above) and xmlCtxtUseOptionsInternal (called below) initialize slightly different context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */ htmlCtxtUseOptions(ctxt, rxml_libxml_default_options()); htmlDefaultSAXHandlerInit(); if (ctxt->sax != NULL) memcpy(ctxt->sax, &htmlDefaultSAXHandler, sizeof(xmlSAXHandlerV1)); return rxml_html_parser_context_wrap(ctxt); } /* * call-seq: * context.close -> nil * * Closes the underlying input streams. This is useful when parsing a large amount of * files and you want to close the files without relying on Ruby's garbage collector * to run. */ static VALUE rxml_html_parser_context_close(VALUE self) { htmlParserCtxtPtr ctxt; xmlParserInputPtr xinput; Data_Get_Struct(self, htmlParserCtxt, ctxt); while ((xinput = inputPop(ctxt)) != NULL) { xmlFreeInputStream(xinput); } return Qnil; } /* * call-seq: * context.disable_cdata = (true|false) * * Control whether the CDATA nodes will be created in this context. */ static VALUE rxml_html_parser_context_disable_cdata_set(VALUE self, VALUE value) { htmlParserCtxtPtr ctxt; Data_Get_Struct(self, htmlParserCtxt, ctxt); if (ctxt->sax == NULL) rb_raise(rb_eRuntimeError, "Sax handler is not yet set"); /* LibXML controls this internally with the default SAX handler. */ if (value) ctxt->sax->cdataBlock = NULL; else ctxt->sax->cdataBlock = htmlDefaultSAXHandler.cdataBlock; return value; } /* * call-seq: * context.options = XML::Parser::Options::NOENT | XML::Parser::Options::NOCDATA * * Provides control over the execution of a parser. Valid values * are the constants defined on XML::Parser::Options. Multiple * options can be combined by using Bitwise OR (|). */ static VALUE rxml_html_parser_context_options_set(VALUE self, VALUE options) { int xml_options = NUM2INT(options); htmlParserCtxtPtr ctxt; Check_Type(options, T_FIXNUM); Data_Get_Struct(self, htmlParserCtxt, ctxt); htmlCtxtUseOptions(ctxt, xml_options); #if LIBXML_VERSION >= 20707 /* Big hack here, but htmlCtxtUseOptions doens't support HTML_PARSE_NOIMPLIED. So do it ourselves. There must be a better way??? */ if (xml_options & HTML_PARSE_NOIMPLIED) { ctxt->options |= HTML_PARSE_NOIMPLIED; } #endif return self; } void rxml_init_html_parser_context(void) { IO_ATTR = ID2SYM(rb_intern("@io")); cXMLHtmlParserContext = rb_define_class_under(cXMLHtmlParser, "Context", cXMLParserContext); rb_define_singleton_method(cXMLHtmlParserContext, "file", rxml_html_parser_context_file, 1); rb_define_singleton_method(cXMLHtmlParserContext, "io", rxml_html_parser_context_io, 1); rb_define_singleton_method(cXMLHtmlParserContext, "string", rxml_html_parser_context_string, 1); rb_define_method(cXMLHtmlParserContext, "close", rxml_html_parser_context_close, 0); rb_define_method(cXMLHtmlParserContext, "disable_cdata=", rxml_html_parser_context_disable_cdata_set, 1); rb_define_method(cXMLHtmlParserContext, "options=", rxml_html_parser_context_options_set, 1); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_schema_element.c0000644000004100000410000000461413760147770023161 0ustar www-datawww-data#include "ruby_libxml.h" #include "ruby_xml_schema_element.h" #include "ruby_xml_schema_type.h" VALUE cXMLSchemaElement; static void rxml_schema_element_free(xmlSchemaElementPtr xschema_element) { xschema_element = NULL; xmlFree(xschema_element); } VALUE rxml_wrap_schema_element(xmlSchemaElementPtr xelement) { return Data_Wrap_Struct(cXMLSchemaElement, NULL, rxml_schema_element_free, xelement); } static VALUE rxml_schema_element_namespace(VALUE self) { xmlSchemaElementPtr xelem; Data_Get_Struct(self, xmlSchemaElement, xelem); QNIL_OR_STRING(xelem->targetNamespace) } static VALUE rxml_schema_element_name(VALUE self) { xmlSchemaElementPtr xelem; Data_Get_Struct(self, xmlSchemaElement, xelem); QNIL_OR_STRING(xelem->name) } static VALUE rxml_schema_element_type(VALUE self) { xmlSchemaElementPtr xelem; xmlSchemaTypePtr xtype; Data_Get_Struct(self, xmlSchemaElement, xelem); xtype = xelem->subtypes; return rxml_wrap_schema_type((xmlSchemaTypePtr) xtype); } static VALUE rxml_schema_element_node(VALUE self) { xmlSchemaElementPtr xelem; Data_Get_Struct(self, xmlSchemaElement, xelem); return rxml_node_wrap(xelem->node); } static VALUE rxml_schema_element_value(VALUE self) { xmlSchemaElementPtr xelem; Data_Get_Struct(self, xmlSchemaElement, xelem); QNIL_OR_STRING(xelem->value) } static VALUE rxml_schema_element_annot(VALUE self) { VALUE result = Qnil; xmlSchemaElementPtr xelem; Data_Get_Struct(self, xmlSchemaElement, xelem); if (xelem != NULL && xelem->annot != NULL && xelem->annot->content != NULL) { xmlChar *content = xmlNodeGetContent(xelem->annot->content); if (content) { result = rxml_new_cstr(content, NULL); xmlFree(content); } } return result; } void rxml_init_schema_element(void) { cXMLSchemaElement = rb_define_class_under(cXMLSchema, "Element", rb_cObject); rb_define_method(cXMLSchemaElement, "namespace", rxml_schema_element_namespace, 0); rb_define_method(cXMLSchemaElement, "name", rxml_schema_element_name, 0); rb_define_method(cXMLSchemaElement, "type", rxml_schema_element_type, 0); rb_define_method(cXMLSchemaElement, "node", rxml_schema_element_node, 0); rb_define_method(cXMLSchemaElement, "value", rxml_schema_element_value, 0); rb_define_method(cXMLSchemaElement, "annotation", rxml_schema_element_annot, 0); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_input_cbg.h0000644000004100000410000000053213760147770022162 0ustar www-datawww-data#ifndef _INPUT_CBG_ #define _INPUT_CBG_ void rxml_init_input_callbacks(void); typedef struct ic_doc_context { char *buffer; char *bpos; int remaining; } ic_doc_context; typedef struct ic_scheme { char *scheme_name; VALUE class; int name_len; struct ic_scheme *next_scheme; } ic_scheme; #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_xpath.c0000644000004100000410000001405113760147770021330 0ustar www-datawww-data/* * Document-class: LibXML::XML::XPath * * The XML::XPath module is used to query XML documents. It is * usually accessed via the XML::Document#find or * XML::Node#find methods. For example: * * document.find('/foo', namespaces) -> XML::XPath::Object * * The optional namespaces parameter can be a string, array or * hash table. * * document.find('/foo', 'xlink:http://www.w3.org/1999/xlink') * document.find('/foo', ['xlink:http://www.w3.org/1999/xlink', * 'xi:http://www.w3.org/2001/XInclude') * document.find('/foo', 'xlink' => 'http://www.w3.org/1999/xlink', * 'xi' => 'http://www.w3.org/2001/XInclude') * * * === Working With Default Namespaces * * Finding namespaced elements and attributes can be tricky. * Lets work through an example of a document with a default * namespace: * * * * Phil Bogle's Contacts * * * To find nodes you must define the atom namespace for * libxml. One way to do this is: * * node = doc.find('atom:title', 'atom:http://www.w3.org/2005/Atom') * * Alternatively, you can register the default namespace like this: * * doc.root.namespaces.default_prefix = 'atom' * node = doc.find('atom:title') * * === More Complex Namespace Examples * * Lets work through some more complex examples using the * following xml document: * * * * * * * * * * * * # Since the soap namespace is defined on the root * # node we can directly use it. * doc.find('/soap:Envelope') * * # Since the ns1 namespace is not defined on the root node * # we have to first register it with the xpath engine. * doc.find('//ns1:IdAndName', * 'ns1:http://domain.somewhere.com') * * # Since the getManufacturerNamesResponse element uses a default * # namespace we first have to give it a prefix and register * # it with the xpath engine. * doc.find('//ns:getManufacturerNamesResponse', * 'ns:http://services.somewhere.com') * * # Here is an example showing a complex namespace aware * # xpath expression. * doc.find('/soap:Envelope/soap:Body/ns0:getManufacturerNamesResponse/ns0:IDAndNameList/ns1:IdAndName', * ['ns0:http://services.somewhere.com', 'ns1:http://domain.somewhere.com']) */ #include "ruby_libxml.h" VALUE mXPath; VALUE rxml_xpath_to_value(xmlXPathContextPtr xctxt, xmlXPathObjectPtr xobject) { VALUE result; int type; if (xobject == NULL) { /* xmlLastError is different than xctxt->lastError. Use xmlLastError since it has the message set while xctxt->lastError does not. */ xmlErrorPtr xerror = xmlGetLastError(); rxml_raise(xerror); } switch (type = xobject->type) { case XPATH_NODESET: result = rxml_xpath_object_wrap(xctxt->doc, xobject); break; case XPATH_BOOLEAN: result = (xobject->boolval != 0) ? Qtrue : Qfalse; xmlXPathFreeObject(xobject); break; case XPATH_NUMBER: result = rb_float_new(xobject->floatval); xmlXPathFreeObject(xobject); break; case XPATH_STRING: result = rxml_new_cstr(xobject->stringval, xctxt->doc->encoding); xmlXPathFreeObject(xobject); break; default: xmlXPathFreeObject(xobject); rb_raise(rb_eTypeError, "can't convert XPath object of type %d to Ruby value", type ); } return result; } xmlXPathObjectPtr rxml_xpath_from_value(VALUE value) { xmlXPathObjectPtr result = NULL; switch (TYPE(value)) { case T_TRUE: case T_FALSE: result = xmlXPathNewBoolean(RTEST(value)); break; case T_FIXNUM: case T_FLOAT: result = xmlXPathNewFloat(NUM2DBL(value)); break; case T_STRING: result = xmlXPathWrapString(xmlStrdup((const xmlChar *)StringValuePtr(value))); break; case T_NIL: result = xmlXPathNewNodeSet(NULL); break; case T_ARRAY: { long i, j; result = xmlXPathNewNodeSet(NULL); for (i = RARRAY_LEN(value); i > 0; i--) { xmlXPathObjectPtr obj = rxml_xpath_from_value(rb_ary_shift(value)); if ((obj->nodesetval != NULL) && (obj->nodesetval->nodeNr != 0)) { for (j = 0; j < obj->nodesetval->nodeNr; j++) { xmlXPathNodeSetAdd(result->nodesetval, obj->nodesetval->nodeTab[j]); } } } break; } default: rb_raise(rb_eTypeError, "can't convert object of type %s to XPath object", rb_obj_classname(value) ); } return result; } void rxml_init_xpath(void) { mXPath = rb_define_module_under(mXML, "XPath"); /* 0: Undefined value. */ rb_define_const(mXPath, "UNDEFINED", INT2NUM(XPATH_UNDEFINED)); /* 1: A nodeset, will be wrapped by XPath Object. */ rb_define_const(mXPath, "NODESET", INT2NUM(XPATH_NODESET)); /* 2: A boolean value. */ rb_define_const(mXPath, "BOOLEAN", INT2NUM(XPATH_BOOLEAN)); /* 3: A numeric value. */ rb_define_const(mXPath, "NUMBER", INT2NUM(XPATH_NUMBER)); /* 4: A string value. */ rb_define_const(mXPath, "STRING", INT2NUM(XPATH_STRING)); /* 5: An xpointer point */ rb_define_const(mXPath, "POINT", INT2NUM(XPATH_POINT)); /* 6: An xpointer range */ rb_define_const(mXPath, "RANGE", INT2NUM(XPATH_RANGE)); /* 7: An xpointer location set */ rb_define_const(mXPath, "LOCATIONSET", INT2NUM(XPATH_LOCATIONSET)); /* 8: XPath user type */ rb_define_const(mXPath, "USERS", INT2NUM(XPATH_USERS)); /* 9: An XSLT value tree, non modifiable */ rb_define_const(mXPath, "XSLT_TREE", INT2NUM(XPATH_XSLT_TREE)); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_xpath_context.c0000644000004100000410000002421613760147770023100 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include "ruby_libxml.h" #include "ruby_xml_xpath_context.h" #include "ruby_xml_xpath_expression.h" #if RUBY_ST_H #include #else #include #endif /* * Document-class: LibXML::XML::XPath::Context * * The XML::XPath::Context class is used to evaluate XPath * expressions. Generally, you should not directly use this class, * but instead use the XML::Document#find and XML::Node#find methods. * * doc = XML::Document.string('
content
') * context = XPath::Context.new(doc) * context.node = doc.root * context.register_namespaces_from_node(doc.root) * nodes = context.find('/header') */ VALUE cXMLXPathContext; static void rxml_xpath_context_free(xmlXPathContextPtr ctxt) { xmlXPathFreeContext(ctxt); } static void rxml_xpath_context_mark(xmlXPathContextPtr ctxt) { VALUE value = (VALUE)ctxt->doc->_private; rb_gc_mark(value); } static VALUE rxml_xpath_context_alloc(VALUE klass) { return Data_Wrap_Struct(cXMLXPathContext, rxml_xpath_context_mark, rxml_xpath_context_free, NULL); } /* call-seq: * XPath::Context.new(doc) -> XPath::Context * * Creates a new XPath context for the specified document. The * context can then be used to evaluate an XPath expression. * * doc = XML::Document.string('
hi
') * context = XPath::Context.new(doc) * nodes = XPath::Object.new('//first', context) * nodes.length == 1 */ static VALUE rxml_xpath_context_initialize(VALUE self, VALUE document) { xmlDocPtr xdoc; if (rb_obj_is_kind_of(document, cXMLDocument) != Qtrue) { rb_raise(rb_eTypeError, "Supplied argument must be a document or node."); } Data_Get_Struct(document, xmlDoc, xdoc); DATA_PTR(self) = xmlXPathNewContext(xdoc); return self; } /* * call-seq: * context.doc -> document * * Obtain the XML::Document this node belongs to. */ static VALUE rxml_xpath_context_doc(VALUE self) { xmlDocPtr xdoc = NULL; xmlXPathContextPtr ctxt; Data_Get_Struct(self, xmlXPathContext, ctxt); xdoc = ctxt->doc; return rxml_document_wrap(xdoc); } /* * call-seq: * context.register_namespace(prefix, uri) -> (true|false) * * Register the specified namespace URI with the specified prefix * in this context. * context.register_namespace('xi', 'http://www.w3.org/2001/XInclude') */ static VALUE rxml_xpath_context_register_namespace(VALUE self, VALUE prefix, VALUE uri) { xmlXPathContextPtr ctxt; Data_Get_Struct(self, xmlXPathContext, ctxt); /* Prefix could be a symbol. */ prefix = rb_obj_as_string(prefix); if (xmlXPathRegisterNs(ctxt, (xmlChar*) StringValuePtr(prefix), (xmlChar*) StringValuePtr(uri)) == 0) { return (Qtrue); } else { /* Should raise an exception, IMHO (whose?, why shouldnt it? -danj)*/ rb_warning("register namespace failed"); return (Qfalse); } } /* call-seq: * context.register_namespaces_from_node(node) -> self * * Helper method to read in namespaces defined on a node. * * doc = XML::Document.string('
hi
') * context = XPath::Context.new(doc) * context.register_namespaces_from_node(doc.root) */ static VALUE rxml_xpath_context_register_namespaces_from_node(VALUE self, VALUE node) { xmlXPathContextPtr xctxt; xmlNodePtr xnode; xmlNsPtr *xnsArr; Data_Get_Struct(self, xmlXPathContext, xctxt); if (rb_obj_is_kind_of(node, cXMLDocument) == Qtrue) { xmlDocPtr xdoc; Data_Get_Struct(node, xmlDoc, xdoc); xnode = xmlDocGetRootElement(xdoc); } else if (rb_obj_is_kind_of(node, cXMLNode) == Qtrue) { Data_Get_Struct(node, xmlNode, xnode); } else { rb_raise(rb_eTypeError, "The first argument must be a document or node."); } xnsArr = xmlGetNsList(xnode->doc, xnode); if (xnsArr) { xmlNsPtr xns = *xnsArr; while (xns) { /* If there is no prefix, then this is the default namespace. Skip it for now. */ if (xns->prefix) { VALUE prefix = rxml_new_cstr(xns->prefix, xctxt->doc->encoding); VALUE uri = rxml_new_cstr(xns->href, xctxt->doc->encoding); rxml_xpath_context_register_namespace(self, prefix, uri); } xns = xns->next; } xmlFree(xnsArr); } return self; } static int iterate_ns_hash(VALUE prefix, VALUE uri, VALUE self) { rxml_xpath_context_register_namespace(self, prefix, uri); return ST_CONTINUE; } /* * call-seq: * context.register_namespaces(["prefix:uri"]) -> self * * Register the specified namespaces in this context. There are * three different forms that libxml accepts. These include * a string, an array of strings, or a hash table: * * context.register_namespaces('xi:http://www.w3.org/2001/XInclude') * context.register_namespaces(['xlink:http://www.w3.org/1999/xlink', * 'xi:http://www.w3.org/2001/XInclude') * context.register_namespaces('xlink' => 'http://www.w3.org/1999/xlink', * 'xi' => 'http://www.w3.org/2001/XInclude') */ static VALUE rxml_xpath_context_register_namespaces(VALUE self, VALUE nslist) { char *cp; long i; VALUE rprefix, ruri; xmlXPathContextPtr xctxt; Data_Get_Struct(self, xmlXPathContext, xctxt); /* Need to loop through the 2nd argument and iterate through the * list of namespaces that we want to allow */ switch (TYPE(nslist)) { case T_STRING: cp = strchr(StringValuePtr(nslist), (int) ':'); if (cp == NULL) { rprefix = nslist; ruri = Qnil; } else { rprefix = rb_str_new(StringValuePtr(nslist), (long) ((intptr_t) cp - (intptr_t)StringValuePtr(nslist))); ruri = rxml_new_cstr((const xmlChar*)&cp[1], xctxt->doc->encoding); } /* Should test the results of this */ rxml_xpath_context_register_namespace(self, rprefix, ruri); break; case T_ARRAY: for (i = 0; i < RARRAY_LEN(nslist); i++) { rxml_xpath_context_register_namespaces(self, RARRAY_PTR(nslist)[i]); } break; case T_HASH: rb_hash_foreach(nslist, iterate_ns_hash, self); break; default: rb_raise( rb_eArgError, "Invalid argument type, only accept string, array of strings, or an array of arrays"); } return self; } /* * call-seq: * context.node = node * * Set the current node used by the XPath engine * doc = XML::Document.string('
hi
') * context.node = doc.root.first */ static VALUE rxml_xpath_context_node_set(VALUE self, VALUE node) { xmlXPathContextPtr xctxt; xmlNodePtr xnode; Data_Get_Struct(self, xmlXPathContext, xctxt); Data_Get_Struct(node, xmlNode, xnode); xctxt->node = xnode; return node; } /* * call-seq: * context.find("xpath") -> true|false|number|string|XML::XPath::Object * * Executes the provided xpath function. The result depends on the execution * of the xpath statement. It may be true, false, a number, a string or * a node set. */ static VALUE rxml_xpath_context_find(VALUE self, VALUE xpath_expr) { xmlXPathContextPtr xctxt; xmlXPathObjectPtr xobject; xmlXPathCompExprPtr xcompexpr; Data_Get_Struct(self, xmlXPathContext, xctxt); if (TYPE(xpath_expr) == T_STRING) { VALUE expression = rb_check_string_type(xpath_expr); xobject = xmlXPathEval((xmlChar*) StringValueCStr(expression), xctxt); } else if (rb_obj_is_kind_of(xpath_expr, cXMLXPathExpression)) { Data_Get_Struct(xpath_expr, xmlXPathCompExpr, xcompexpr); xobject = xmlXPathCompiledEval(xcompexpr, xctxt); } else { rb_raise(rb_eTypeError, "Argument should be an instance of a String or XPath::Expression"); } return rxml_xpath_to_value(xctxt, xobject); } #if LIBXML_VERSION >= 20626 /* * call-seq: * context.enable_cache(size = nil) * * Enables an XPath::Context's built-in cache. If the cache is * enabled then XPath objects will be cached internally for reuse. * The size parameter controls sets the maximum number of XPath objects * that will be cached per XPath object type (node-set, string, number, * boolean, and misc objects). Set size to nil to use the default * cache size of 100. */ static VALUE rxml_xpath_context_enable_cache(int argc, VALUE *argv, VALUE self) { xmlXPathContextPtr xctxt; VALUE size; int value = -1; Data_Get_Struct(self, xmlXPathContext, xctxt); if (rb_scan_args(argc, argv, "01", &size) == 1) { value = NUM2INT(size); } if (xmlXPathContextSetCache(xctxt, 1, value, 0) == -1) rxml_raise(&xmlLastError); return self; } /* * call-seq: * context.disable_cache * * Disables an XPath::Context's built-in cache. */ static VALUE rxml_xpath_context_disable_cache(VALUE self) { xmlXPathContextPtr xctxt; Data_Get_Struct(self, xmlXPathContext, xctxt); if (xmlXPathContextSetCache(xctxt, 0, 0, 0) == -1) rxml_raise(&xmlLastError); return self; } #endif void rxml_init_xpath_context(void) { cXMLXPathContext = rb_define_class_under(mXPath, "Context", rb_cObject); rb_define_alloc_func(cXMLXPathContext, rxml_xpath_context_alloc); rb_define_method(cXMLXPathContext, "doc", rxml_xpath_context_doc, 0); rb_define_method(cXMLXPathContext, "initialize", rxml_xpath_context_initialize, 1); rb_define_method(cXMLXPathContext, "register_namespaces", rxml_xpath_context_register_namespaces, 1); rb_define_method(cXMLXPathContext, "register_namespaces_from_node", rxml_xpath_context_register_namespaces_from_node, 1); rb_define_method(cXMLXPathContext, "register_namespace", rxml_xpath_context_register_namespace, 2); rb_define_method(cXMLXPathContext, "node=", rxml_xpath_context_node_set, 1); rb_define_method(cXMLXPathContext, "find", rxml_xpath_context_find, 1); #if LIBXML_VERSION >= 20626 rb_define_method(cXMLXPathContext, "enable_cache", rxml_xpath_context_enable_cache, -1); rb_define_method(cXMLXPathContext, "disable_cache", rxml_xpath_context_disable_cache, 0); #endif } libxml-ruby-3.2.1/ext/libxml/ruby_xml_writer.c0000644000004100000410000010777613760147770021541 0ustar www-datawww-data#include "ruby_libxml.h" #include "ruby_xml_writer.h" VALUE cXMLWriter; static VALUE sEncoding, sStandalone; #ifdef LIBXML_WRITER_ENABLED /* * Document-class: LibXML::XML::Writer * * The XML::Writer class provides a simpler, alternative way to build a valid * XML document from scratch (forward-only) compared to a DOM approach (based * on XML::Document class). * * For a more in depth tutorial, albeit in C, see http://xmlsoft.org/xmlwriter.html */ #include typedef enum { RXMLW_OUTPUT_NONE, RXMLW_OUTPUT_IO, RXMLW_OUTPUT_DOC, RXMLW_OUTPUT_STRING } rxmlw_output_type; typedef struct { VALUE output; rb_encoding* encoding; xmlBufferPtr buffer; xmlTextWriterPtr writer; rxmlw_output_type output_type; int closed; } rxml_writer_object; static void rxml_writer_free(rxml_writer_object* rwo) { #if 0 /* seems to be done by xmlFreeTextWriter */ if (NULL != rwo->buffer) { xmlBufferFree(rwo->buffer); } #endif rwo->closed = 1; xmlFreeTextWriter(rwo->writer); xfree(rwo); } static void rxml_writer_mark(rxml_writer_object* rwo) { if (!NIL_P(rwo->output)) { rb_gc_mark(rwo->output); } } static VALUE rxml_writer_wrap(rxml_writer_object* rwo) { return Data_Wrap_Struct(cXMLWriter, rxml_writer_mark, rxml_writer_free, rwo); } static rxml_writer_object* rxml_textwriter_get(VALUE obj) { rxml_writer_object* rwo; Data_Get_Struct(obj, rxml_writer_object, rwo); return rwo; } int rxml_writer_write_callback(void* context, const char* buffer, int len) { rxml_writer_object* rwo = context; if (rwo->closed) { return 0; } else { return rxml_write_callback(rwo->output, buffer, len); } } /* ===== public class methods ===== */ /* call-seq: * XML::Writer::io(io) -> XML::Writer * * Creates a XML::Writer which will write XML directly into an IO object. */ static VALUE rxml_writer_io(VALUE klass, VALUE io) { xmlOutputBufferPtr out; rxml_writer_object* rwo; rwo = ALLOC(rxml_writer_object); rwo->output = io; rwo->buffer = NULL; rwo->closed = 0; rwo->encoding = rb_enc_get(io); if (!rwo->encoding) rwo->encoding = rb_utf8_encoding(); rwo->output_type = RXMLW_OUTPUT_IO; xmlCharEncodingHandlerPtr encodingHdlr = xmlFindCharEncodingHandler(rwo->encoding->name); if (NULL == (out = xmlOutputBufferCreateIO(rxml_writer_write_callback, NULL, (void*)rwo, encodingHdlr))) { rxml_raise(&xmlLastError); } if (NULL == (rwo->writer = xmlNewTextWriter(out))) { rxml_raise(&xmlLastError); } return rxml_writer_wrap(rwo); } /* call-seq: * XML::Writer::file(path) -> XML::Writer * * Creates a XML::Writer object which will write XML into the file with * the given name. */ static VALUE rxml_writer_file(VALUE klass, VALUE filename) { rxml_writer_object* rwo; rwo = ALLOC(rxml_writer_object); rwo->output = Qnil; rwo->buffer = NULL; rwo->closed = 0; rwo->encoding = rb_utf8_encoding(); rwo->output_type = RXMLW_OUTPUT_NONE; if (NULL == (rwo->writer = xmlNewTextWriterFilename(StringValueCStr(filename), 0))) { rxml_raise(&xmlLastError); } return rxml_writer_wrap(rwo); } /* call-seq: * XML::Writer::string -> XML::Writer * * Creates a XML::Writer which will write XML into memory, as string. */ static VALUE rxml_writer_string(VALUE klass) { rxml_writer_object* rwo; rwo = ALLOC(rxml_writer_object); rwo->output = Qnil; rwo->closed = 0; rwo->encoding = rb_utf8_encoding(); rwo->output_type = RXMLW_OUTPUT_STRING; if (NULL == (rwo->buffer = xmlBufferCreate())) { rxml_raise(&xmlLastError); } if (NULL == (rwo->writer = xmlNewTextWriterMemory(rwo->buffer, 0))) { xmlBufferFree(rwo->buffer); rxml_raise(&xmlLastError); } return rxml_writer_wrap(rwo); } /* call-seq: * XML::Writer::document -> XML::Writer * * Creates a XML::Writer which will write into an in memory XML::Document */ static VALUE rxml_writer_doc(VALUE klass) { xmlDocPtr doc; rxml_writer_object* rwo; rwo = ALLOC(rxml_writer_object); rwo->buffer = NULL; rwo->output = Qnil; rwo->closed = 0; rwo->encoding = rb_utf8_encoding(); rwo->output_type = RXMLW_OUTPUT_DOC; if (NULL == (rwo->writer = xmlNewTextWriterDoc(&doc, 0))) { rxml_raise(&xmlLastError); } rwo->output = rxml_document_wrap(doc); return rxml_writer_wrap(rwo); } /* ===== public instance methods ===== */ /* call-seq: * writer.flush(empty? = true) -> (num|string) * * Flushes the output buffer. Returns the number of written bytes or * the current content of the internal buffer for a in memory XML::Writer. * If +empty?+ is +true+, and for a in memory XML::Writer, this internel * buffer is empty. */ static VALUE rxml_writer_flush(int argc, VALUE* argv, VALUE self) { int ret; VALUE empty; rxml_writer_object* rwo; rb_scan_args(argc, argv, "01", &empty); rwo = rxml_textwriter_get(self); if (-1 == (ret = xmlTextWriterFlush(rwo->writer))) { rxml_raise(&xmlLastError); } if (NULL != rwo->buffer) { VALUE content; content = rb_external_str_new_with_enc((const char*)rwo->buffer->content, rwo->buffer->use, rwo->encoding); if (NIL_P(empty) || RTEST(empty)) { /* nil = default value = true */ xmlBufferEmpty(rwo->buffer); } return content; } else { return INT2NUM(ret); } } /* call-seq: * writer.result -> (XML::Document|"string"|nil) * * Returns the associated result object to the XML::Writer creation. * A String for a XML::Writer object created with XML::Writer::string, * a XML::Document with XML::Writer::document, etc. */ static VALUE rxml_writer_result(VALUE self) { VALUE ret = Qnil; rxml_writer_object* rwo = rxml_textwriter_get(self); int bytesWritten = xmlTextWriterFlush(rwo->writer); if (bytesWritten == -1) { rxml_raise(&xmlLastError); } switch (rwo->output_type) { case RXMLW_OUTPUT_DOC: ret = rwo->output; break; case RXMLW_OUTPUT_STRING: ret = rb_external_str_new_with_enc((const char*)rwo->buffer->content, rwo->buffer->use, rwo->encoding); break; case RXMLW_OUTPUT_IO: case RXMLW_OUTPUT_NONE: break; default: rb_bug("unexpected output"); break; } return ret; } /* ===== private helpers ===== */ static VALUE numeric_rxml_writer_void(VALUE obj, int (*fn)(xmlTextWriterPtr)) { int ret; rxml_writer_object* rwo; rwo = rxml_textwriter_get(obj); ret = fn(rwo->writer); return (-1 == ret ? Qfalse : Qtrue); } #define numeric_rxml_writer_string(/*VALUE*/ obj, /*VALUE*/ name_or_content, /*int (**/fn/*)(xmlTextWriterPtr, const xmlChar *)*/) \ numeric_rxml_writer_va_strings(obj, Qundef, 1, fn, name_or_content) /** * This is quite ugly but thanks to libxml2 coding style, all xmlTextWriter* * calls can be redirected to a single function. This can be convenient to: * - avoid repeating yourself * - convert strings to UTF-8 * - validate names * and so on **/ #define XMLWRITER_MAX_STRING_ARGS 5 static VALUE numeric_rxml_writer_va_strings(VALUE obj, VALUE pe, size_t strings_count, int (*fn)(ANYARGS), ...) { va_list ap; size_t argc; int ret = -1; rxml_writer_object* rwo; const xmlChar* argv[XMLWRITER_MAX_STRING_ARGS]; VALUE utf8[XMLWRITER_MAX_STRING_ARGS], orig[XMLWRITER_MAX_STRING_ARGS]; if (strings_count > XMLWRITER_MAX_STRING_ARGS) { rb_bug("more arguments than expected"); } va_start(ap, fn); rwo = rxml_textwriter_get(obj); for (argc = 0; argc < strings_count; argc++) { VALUE arg; arg = va_arg(ap, VALUE); orig[argc] = arg; if (NIL_P(arg)) { utf8[argc] = Qnil; argv[argc] = NULL; } else { utf8[argc] = rb_str_conv_enc(orig[argc], rb_enc_get(orig[argc]), rwo->encoding); argv[argc] = BAD_CAST StringValueCStr(utf8[argc]); } } va_end(ap); if (Qundef == pe) { switch (strings_count) { case 0: ret = fn(rwo->writer); break; case 1: ret = fn(rwo->writer, argv[0]); break; case 2: ret = fn(rwo->writer, argv[0], argv[1]); break; case 3: ret = fn(rwo->writer, argv[0], argv[1], argv[2]); break; case 4: ret = fn(rwo->writer, argv[0], argv[1], argv[2], argv[3]); break; case 5: ret = fn(rwo->writer, argv[0], argv[1], argv[2], argv[3], argv[4]); break; default: break; } } else { int xpe; xpe = RTEST(pe); switch (strings_count) { /* strings_count doesn't include pe */ case 0: ret = fn(rwo->writer, xpe); break; case 1: ret = fn(rwo->writer, xpe, argv[0]); break; case 2: ret = fn(rwo->writer, xpe, argv[0], argv[1]); break; case 3: ret = fn(rwo->writer, xpe, argv[0], argv[1], argv[2]); break; case 4: ret = fn(rwo->writer, xpe, argv[0], argv[1], argv[2], argv[3]); break; case 5: ret = fn(rwo->writer, xpe, argv[0], argv[1], argv[2], argv[3], argv[4]); break; default: break; } } while (--strings_count > 0) { if (!NIL_P(orig[strings_count])) { if (orig[strings_count] != utf8[strings_count]) { rb_str_free(utf8[strings_count]); } } } return (-1 == ret ? Qfalse : Qtrue); } /* ===== public instance methods ===== */ #if LIBXML_VERSION >= 20605 /* call-seq: * writer.set_indent(indentation) -> (true|false) * * Toggles indentation on or off. Returns +false+ on failure. * * Availability: libxml2 >= 2.6.5 */ static VALUE rxml_writer_set_indent(VALUE self, VALUE indentation) { int ret; rxml_writer_object* rwo; rwo = rxml_textwriter_get(self); ret = xmlTextWriterSetIndent(rwo->writer, RTEST(indentation)); return (-1 == ret ? Qfalse : Qtrue); } /* call-seq: * writer.set_indent_string(string) -> (true|false) * * Sets the string to use to indent each element of the document. * Don't forget to enable indentation with set_indent. Returns * +false+ on failure. * * Availability: libxml2 >= 2.6.5 */ static VALUE rxml_writer_set_indent_string(VALUE self, VALUE indentation) { return numeric_rxml_writer_string(self, indentation, xmlTextWriterSetIndentString); } #endif /* LIBXML_VERSION >= 20605 */ /* ===== public full tag interface ===== */ /* write_ = start_ + write_string + end_ */ /* call-seq: * writer.write_comment(content) -> (true|false) * * Writes a full comment tag, all at once. Returns +false+ on failure. * This is equivalent to start_comment + write_string(content) + end_comment. */ static VALUE rxml_writer_write_comment(VALUE self, VALUE content) { return numeric_rxml_writer_string(self, content, xmlTextWriterWriteComment); } /* call-seq: * writer.write_cdata(content) -> (true|false) * * Writes a full CDATA section, all at once. Returns +false+ on failure. * This is equivalent to start_cdata + write_string(content) + end_cdata. */ static VALUE rxml_writer_write_cdata(VALUE self, VALUE content) { return numeric_rxml_writer_string(self, content, xmlTextWriterWriteCDATA); } static VALUE rxml_writer_start_element(VALUE, VALUE); static VALUE rxml_writer_start_element_ns(int, VALUE*, VALUE); static VALUE rxml_writer_end_element(VALUE); /* call-seq: * writer.write_element(name, content) -> (true|false) * * Writes a full element tag, all at once. Returns +false+ on failure. * This is equivalent to start_element(name) + write_string(content) + * end_element. */ static VALUE rxml_writer_write_element(int argc, VALUE* argv, VALUE self) { VALUE name, content; rb_scan_args(argc, argv, "11", &name, &content); if (Qnil == content) { if (Qfalse == rxml_writer_start_element(self, name)) { return Qfalse; } return rxml_writer_end_element(self); } else { return numeric_rxml_writer_va_strings(self, Qundef, 2, xmlTextWriterWriteElement, name, content); } } #define ARRAY_SIZE(array) \ (sizeof(array) / sizeof((array)[0])) /* call-seq: * writer.write_element_ns(prefix, name, namespaceURI, content) -> (true|false) * * Writes a full namespaced element tag, all at once. Returns +false+ on failure. * This is a shortcut for start_element_ns(prefix, name, namespaceURI) + * write_string(content) + end_element. * * Notes: * - by default, the xmlns: definition is repeated on every element. If you want * the prefix, but don't want the xmlns: declaration repeated, set +namespaceURI+ * to nil or omit it. Don't forget to declare the namespace prefix somewhere * earlier. * - +content+ can be omitted for an empty tag */ static VALUE rxml_writer_write_element_ns(int argc, VALUE* argv, VALUE self) { VALUE prefix, name, namespaceURI, content; rb_scan_args(argc, argv, "22", &prefix, &name, &namespaceURI, &content); if (Qnil == content) { VALUE argv[3] = { prefix, name, namespaceURI }; if (Qfalse == rxml_writer_start_element_ns(ARRAY_SIZE(argv), argv, self)) { return Qfalse; } return rxml_writer_end_element(self); } else { return numeric_rxml_writer_va_strings(self, Qundef, 4, xmlTextWriterWriteElementNS, prefix, name, namespaceURI, content); } } /* call-seq: * writer.write_attribute(name, content) -> (true|false) * * Writes a full attribute, all at once. Returns +false+ on failure. * Same as start_attribute(name) + write_string(content) + end_attribute. */ static VALUE rxml_writer_write_attribute(VALUE self, VALUE name, VALUE content) { return numeric_rxml_writer_va_strings(self, Qundef, 2, xmlTextWriterWriteAttribute, name, content); } /* call-seq: * writer.write_attribute_ns(prefix, name, namespaceURI, content) -> (true|false) * * Writes a full namespaced attribute, all at once. Returns +false+ on failure. * Same as start_attribute_ns(prefix, name, namespaceURI) + * write_string(content) + end_attribute. * * Notes: * - by default, the xmlns: definition is repeated on every element. If you want * the prefix, but don't want the xmlns: declaration repeated, set +namespaceURI+ * to nil or omit it. Don't forget to declare the namespace prefix somewhere * earlier. * - +content+ can be omitted too for an empty attribute */ static VALUE rxml_writer_write_attribute_ns(int argc, VALUE* argv, VALUE self) { VALUE prefix, name, namespaceURI, content; rb_scan_args(argc, argv, "22", &prefix, &name, &namespaceURI, &content); return numeric_rxml_writer_va_strings(self, Qundef, 4, xmlTextWriterWriteAttributeNS, prefix, name, namespaceURI, content); } /* call-seq: * writer.write_pi(target, content) -> (true|false) * * Writes a full CDATA tag, all at once. Returns +false+ on failure. * This is a shortcut for start_pi(target) + write_string(content) + end_pi. */ static VALUE rxml_writer_write_pi(VALUE self, VALUE target, VALUE content) { return numeric_rxml_writer_va_strings(self, Qundef, 2, xmlTextWriterWritePI, target, content); } /* ===== public start/end interface ===== */ /* call-seq: * writer.write_string(content) -> (true|false) * * Safely (problematic characters are internally translated to their * associated named entities) writes a string into the current node * (attribute, element, comment, ...). Returns +false+ on failure. */ static VALUE rxml_writer_write_string(VALUE self, VALUE content) { return numeric_rxml_writer_string(self, content, xmlTextWriterWriteString); } /* call-seq: * writer.write_raw(content) -> (true|false) * * Writes the string +content+ as is, reserved characters are not * translated to their associated entities. Returns +false+ on failure. * Consider write_string to handle them. */ static VALUE rxml_writer_write_raw(VALUE self, VALUE content) { return numeric_rxml_writer_string(self, content, xmlTextWriterWriteRaw); } /* call-seq: * writer.start_attribute(name) -> (true|false) * * Starts an attribute. Returns +false+ on failure. */ static VALUE rxml_writer_start_attribute(VALUE self, VALUE name) { return numeric_rxml_writer_string(self, name, xmlTextWriterStartAttribute); } /* call-seq: * writer.start_attribute_ns(prefix, name, namespaceURI) -> (true|false) * * Starts a namespaced attribute. Returns +false+ on failure. * * Note: by default, the xmlns: definition is repeated on every element. If * you want the prefix, but don't want the xmlns: declaration repeated, set * +namespaceURI+ to nil or omit it. Don't forget to declare the namespace * prefix somewhere earlier. */ static VALUE rxml_writer_start_attribute_ns(int argc, VALUE* argv, VALUE self) { VALUE prefix, name, namespaceURI; rb_scan_args(argc, argv, "21", &prefix, &name, &namespaceURI); return numeric_rxml_writer_va_strings(self, Qundef, 3, xmlTextWriterStartAttributeNS, prefix, name, namespaceURI); } /* call-seq: * writer.end_attribute -> (true|false) * * Ends an attribute, namespaced or not. Returns +false+ on failure. */ static VALUE rxml_writer_end_attribute(VALUE self) { return numeric_rxml_writer_void(self, xmlTextWriterEndAttribute); } #if LIBXML_VERSION >= 20607 /* call-seq: * writer.start_comment -> (true|false) * * Starts a comment. Returns +false+ on failure. * Note: libxml2 >= 2.6.7 required */ static VALUE rxml_writer_start_comment(VALUE self) { return numeric_rxml_writer_void(self, xmlTextWriterStartComment); } /* call-seq: * writer.end_comment -> (true|false) * * Ends current comment, returns +false+ on failure. * Note: libxml2 >= 2.6.7 required */ static VALUE rxml_writer_end_comment(VALUE self) { return numeric_rxml_writer_void(self, xmlTextWriterEndComment); } #endif /* LIBXML_VERSION >= 20607 */ /* call-seq: * writer.start_element(name) -> (true|false) * * Starts a new element. Returns +false+ on failure. */ static VALUE rxml_writer_start_element(VALUE self, VALUE name) { return numeric_rxml_writer_string(self, name, xmlTextWriterStartElement); } /* call-seq: * writer.start_element_ns(prefix, name, namespaceURI) -> (true|false) * * Starts a new namespaced element. Returns +false+ on failure. * * Note: by default, the xmlns: definition is repeated on every element. If * you want the prefix, but don't want the xmlns: declaration repeated, set * +namespaceURI+ to nil or omit it. Don't forget to declare the namespace * prefix somewhere earlier. */ static VALUE rxml_writer_start_element_ns(int argc, VALUE* argv, VALUE self) { VALUE prefix, name, namespaceURI; rb_scan_args(argc, argv, "21", &prefix, &name, &namespaceURI); return numeric_rxml_writer_va_strings(self, Qundef, 3, xmlTextWriterStartElementNS, prefix, name, namespaceURI); } /* call-seq: * writer.end_element -> (true|false) * * Ends current element, namespaced or not. Returns +false+ on failure. */ static VALUE rxml_writer_end_element(VALUE self) { return numeric_rxml_writer_void(self, xmlTextWriterEndElement); } /* call-seq: * writer.write_full_end_element -> (true|false) * * Ends current element, namespaced or not. Returns +false+ on failure. * This method writes an end tag even if the element is empty (), * end_element does not (). */ static VALUE rxml_writer_full_end_element(VALUE self) { return numeric_rxml_writer_void(self, xmlTextWriterFullEndElement); } /* call-seq: * writer.start_cdata -> (true|false) * * Starts a new CDATA section. Returns +false+ on failure. */ static VALUE rxml_writer_start_cdata(VALUE self) { return numeric_rxml_writer_void(self, xmlTextWriterStartCDATA); } /* call-seq: * writer.end_cdata -> (true|false) * * Ends current CDATA section. Returns +false+ on failure. */ static VALUE rxml_writer_end_cdata(VALUE self) { return numeric_rxml_writer_void(self, xmlTextWriterEndCDATA); } /* call-seq: * writer.start_document -> (true|false) * writer.start_document(:encoding => XML::Encoding::UTF_8, * :standalone => true) -> (true|false) * * Starts a new document. Returns +false+ on failure. * * You may provide an optional hash table to control XML header that will be * generated. Valid options are: * - encoding: the output document encoding, defaults to nil (= UTF-8). Valid * values are the encoding constants defined on XML::Encoding * - standalone: nil (default) or a boolean to indicate if the document is * standalone or not */ static VALUE rxml_writer_start_document(int argc, VALUE* argv, VALUE self) { int ret; VALUE options = Qnil; rxml_writer_object* rwo; const xmlChar* xencoding = NULL; const char* xstandalone = NULL; rb_scan_args(argc, argv, "01", &options); if (!NIL_P(options)) { VALUE encoding, standalone; encoding = standalone = Qnil; Check_Type(options, T_HASH); encoding = rb_hash_aref(options, sEncoding); xencoding = NIL_P(encoding) ? NULL : (const xmlChar*)xmlGetCharEncodingName(NUM2INT(encoding)); standalone = rb_hash_aref(options, sStandalone); if (NIL_P(standalone)) { xstandalone = NULL; } else { xstandalone = RTEST(standalone) ? "yes" : "no"; } } rwo = rxml_textwriter_get(self); rwo->encoding = rxml_figure_encoding(xencoding); ret = xmlTextWriterStartDocument(rwo->writer, NULL, (const char*)xencoding, xstandalone); return (-1 == ret ? Qfalse : Qtrue); } /* call-seq: * writer.end_document -> (true|false) * * Ends current document. Returns +false+ on failure. */ static VALUE rxml_writer_end_document(VALUE self) { return numeric_rxml_writer_void(self, xmlTextWriterEndDocument); } /* call-seq: * writer.start_pi(target) -> (true|false) * * Starts a new processing instruction. Returns +false+ on failure. */ static VALUE rxml_writer_start_pi(VALUE self, VALUE target) { return numeric_rxml_writer_string(self, target, xmlTextWriterStartPI); } /* call-seq: * writer.end_pi -> (true|false) * * Ends current processing instruction. Returns +false+ on failure. */ static VALUE rxml_writer_end_pi(VALUE self) { return numeric_rxml_writer_void(self, xmlTextWriterEndPI); } /* call-seq: * writer.start_dtd(qualifiedName, publicId, systemId) -> (true|false) * * Starts a DTD. Returns +false+ on failure. */ static VALUE rxml_writer_start_dtd(int argc, VALUE* argv, VALUE self) { VALUE name, pubid, sysid; rb_scan_args(argc, argv, "12", &name, &pubid, &sysid); return numeric_rxml_writer_va_strings(self, Qundef, 3, xmlTextWriterStartDTD, name, pubid, sysid); } /* call-seq: * writer.start_dtd_element(qualifiedName) -> (true|false) * * Starts a DTD element (). Returns +false+ on failure. */ static VALUE rxml_writer_start_dtd_element(VALUE self, VALUE name) { return numeric_rxml_writer_string(self, name, xmlTextWriterStartDTDElement); } /* call-seq: * writer.start_dtd_entity(name, pe = false) -> (true|false) * * Starts a DTD entity (). Returns +false+ on failure. */ static VALUE rxml_writer_start_dtd_entity(int argc, VALUE* argv, VALUE self) { VALUE name, pe; rb_scan_args(argc, argv, "11", &name, &pe); if (NIL_P(pe)) { pe = Qfalse; } return numeric_rxml_writer_va_strings(self, pe, 1, xmlTextWriterStartDTDEntity, name); } /* call-seq: * writer.start_dtd_attlist(name) -> (true|false) * * Starts a DTD attribute list (). Returns +false+ on failure. */ static VALUE rxml_writer_start_dtd_attlist(VALUE self, VALUE name) { return numeric_rxml_writer_string(self, name, xmlTextWriterStartDTDAttlist); } /* call-seq: * writer.end_dtd -> (true|false) * * Ends current DTD, returns +false+ on failure. */ static VALUE rxml_writer_end_dtd(VALUE self) { return numeric_rxml_writer_void(self, xmlTextWriterEndDTD); } /* call-seq: * writer.end_dtd_entity -> (true|false) * * Ends current DTD entity, returns +false+ on failure. */ static VALUE rxml_writer_end_dtd_entity(VALUE self) { return numeric_rxml_writer_void(self, xmlTextWriterEndDTDEntity); } /* call-seq: * writer.end_dtd_attlist -> (true|false) * * Ends current DTD attribute list, returns +false+ on failure. */ static VALUE rxml_writer_end_dtd_attlist(VALUE self) { return numeric_rxml_writer_void(self, xmlTextWriterEndDTDAttlist); } /* call-seq: * writer.end_dtd_element -> (true|false) * * Ends current DTD element, returns +false+ on failure. */ static VALUE rxml_writer_end_dtd_element(VALUE self) { return numeric_rxml_writer_void(self, xmlTextWriterEndDTDElement); } /* call-seq: * writer.write_dtd(name [ [ [, publicId ], systemId ], subset ]) -> (true|false) * * Writes a DTD, all at once. Returns +false+ on failure. * - name: dtd name * - publicId: external subset public identifier, use nil for a SYSTEM doctype * - systemId: external subset system identifier * - subset: content * * Examples: * writer.write_dtd 'html' * #=> * writer.write_dtd 'docbook', nil, 'http://www.docbook.org/xml/5.0/dtd/docbook.dtd' * #=> * writer.write_dtd 'html', '-//W3C//DTD XHTML 1.1//EN', 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd' * #=> * writer.write_dtd 'person', nil, nil, '' * #=> ]> */ static VALUE rxml_writer_write_dtd(int argc, VALUE* argv, VALUE self) { VALUE name, pubid, sysid, subset; rb_scan_args(argc, argv, "13", &name, &pubid, &sysid, &subset); return numeric_rxml_writer_va_strings(self, Qundef, 4, xmlTextWriterWriteDTD, name, pubid, sysid, subset); } /* call-seq: * writer.write_dtd_attlist(name, content) -> (true|false) * * Writes a DTD attribute list, all at once. Returns +false+ on failure. * writer.write_dtd_attlist 'id', 'ID #IMPLIED' * #=> */ static VALUE rxml_writer_write_dtd_attlist(VALUE self, VALUE name, VALUE content) { return numeric_rxml_writer_va_strings(self, Qundef, 2, xmlTextWriterWriteDTDAttlist, name, content); } /* call-seq: * writer.write_dtd_element(name, content) -> (true|false) * * Writes a full DTD element, all at once. Returns +false+ on failure. * writer.write_dtd_element 'person', '(firstname,lastname)' * #=> */ static VALUE rxml_writer_write_dtd_element(VALUE self, VALUE name, VALUE content) { return numeric_rxml_writer_va_strings(self, Qundef, 2, xmlTextWriterWriteDTDElement, name, content); } /* call-seq: * writer.write_dtd_entity(name, publicId, systemId, ndataid, content, pe) -> (true|false) * * Writes a DTD entity, all at once. Returns +false+ on failure. */ static VALUE rxml_writer_write_dtd_entity(VALUE self, VALUE name, VALUE pubid, VALUE sysid, VALUE ndataid, VALUE content, VALUE pe) { return numeric_rxml_writer_va_strings(self, pe, 5, xmlTextWriterWriteDTDEntity, name, pubid, sysid, ndataid, content); } /* call-seq: * writer.write_dtd_external_entity(name, publicId, systemId, ndataid, pe) -> (true|false) * * Writes a DTD external entity. The entity must have been started * with start_dtd_entity. Returns +false+ on failure. * - name: the name of the DTD entity * - publicId: the public identifier, which is an alternative to the system identifier * - systemId: the system identifier, which is the URI of the DTD * - ndataid: the xml notation name * - pe: +true+ if this is a parameter entity (to be used only in the DTD * itself), +false+ if not */ static VALUE rxml_writer_write_dtd_external_entity(VALUE self, VALUE name, VALUE pubid, VALUE sysid, VALUE ndataid, VALUE pe) { return numeric_rxml_writer_va_strings(self, pe, 4, xmlTextWriterWriteDTDExternalEntity, name, pubid, sysid, ndataid); } /* call-seq: * writer.write_dtd_external_entity_contents(publicId, systemId, ndataid) -> (true|false) * * Writes the contents of a DTD external entity, all at once. Returns +false+ on failure. */ static VALUE rxml_writer_write_dtd_external_entity_contents(VALUE self, VALUE pubid, VALUE sysid, VALUE ndataid) { return numeric_rxml_writer_va_strings(self, Qundef, 3, xmlTextWriterWriteDTDExternalEntityContents, pubid, sysid, ndataid); } /* call-seq: * writer.write_dtd_internal_entity(name, content, pe) -> (true|false) * * Writes a DTD internal entity, all at once. Returns +false+ on failure. * * Examples: * writer.write_dtd_entity 'Shape', '(rect|circle|poly|default)', true * #=> * writer.write_dtd_entity 'delta', 'δ', false * #=> */ static VALUE rxml_writer_write_dtd_internal_entity(VALUE self, VALUE name, VALUE content, VALUE pe) { return numeric_rxml_writer_va_strings(self, pe, 2, xmlTextWriterWriteDTDInternalEntity, name, content); } /* call-seq: * writer.write_dtd_notation(name, publicId, systemId) -> (true|false) * * Writes a DTD entity, all at once. Returns +false+ on failure. */ static VALUE rxml_writer_write_dtd_notation(VALUE self, VALUE name, VALUE pubid, VALUE sysid) { return numeric_rxml_writer_va_strings(self, Qundef, 3, xmlTextWriterWriteDTDNotation, name, pubid, sysid); } #if LIBXML_VERSION >= 20900 /* call-seq: * writer.set_quote_char(...) -> (true|false) * * Sets the character used to quote attributes. Returns +false+ on failure. * * Notes: * - only " (default) and ' characters are valid * - availability: libxml2 >= 2.9.0 */ static VALUE rxml_writer_set_quote_char(VALUE self, VALUE quotechar) { int ret; const char* xquotechar; rxml_writer_object* rwo; rwo = rxml_textwriter_get(self); xquotechar = StringValueCStr(quotechar); ret = xmlTextWriterSetQuoteChar(rwo->writer, (xmlChar)xquotechar[0]); return (-1 == ret ? Qfalse : Qtrue); } #endif /* LIBXML_VERSION >= 20900 */ #endif /* LIBXML_WRITER_ENABLED */ /* grep -P 'xmlTextWriter(Start|End|Write)(?!DTD|V?Format)[^(]+' /usr/include/libxml2/libxml/xmlwriter.h */ void rxml_init_writer(void) { sEncoding = ID2SYM(rb_intern("encoding")); sStandalone = ID2SYM(rb_intern("standalone")); cXMLWriter = rb_define_class_under(mXML, "Writer", rb_cObject); #ifdef LIBXML_WRITER_ENABLED rb_define_singleton_method(cXMLWriter, "io", rxml_writer_io, 1); rb_define_singleton_method(cXMLWriter, "file", rxml_writer_file, 1); rb_define_singleton_method(cXMLWriter, "document", rxml_writer_doc, 0); rb_define_singleton_method(cXMLWriter, "string", rxml_writer_string, 0); /* misc */ #if LIBXML_VERSION >= 20605 rb_define_method(cXMLWriter, "set_indent", rxml_writer_set_indent, 1); rb_define_method(cXMLWriter, "set_indent_string", rxml_writer_set_indent_string, 1); #endif /* LIBXML_VERSION >= 20605 */ #if LIBXML_VERSION >= 20900 rb_define_method(cXMLWriter, "set_quote_char", rxml_writer_set_quote_char, 1); #endif /* LIBXML_VERSION >= 20900 */ rb_define_method(cXMLWriter, "flush", rxml_writer_flush, -1); rb_define_method(cXMLWriter, "start_dtd", rxml_writer_start_dtd, -1); rb_define_method(cXMLWriter, "start_dtd_entity", rxml_writer_start_dtd_entity, -1); rb_define_method(cXMLWriter, "start_dtd_attlist", rxml_writer_start_dtd_attlist, 1); rb_define_method(cXMLWriter, "start_dtd_element", rxml_writer_start_dtd_element, 1); rb_define_method(cXMLWriter, "write_dtd", rxml_writer_write_dtd, -1); rb_define_method(cXMLWriter, "write_dtd_attlist", rxml_writer_write_dtd_attlist, 2); rb_define_method(cXMLWriter, "write_dtd_element", rxml_writer_write_dtd_element, 2); rb_define_method(cXMLWriter, "write_dtd_entity", rxml_writer_write_dtd_entity, 6); rb_define_method(cXMLWriter, "write_dtd_external_entity", rxml_writer_write_dtd_external_entity, 5); rb_define_method(cXMLWriter, "write_dtd_external_entity_contents", rxml_writer_write_dtd_external_entity_contents, 3); rb_define_method(cXMLWriter, "write_dtd_internal_entity", rxml_writer_write_dtd_internal_entity, 3); rb_define_method(cXMLWriter, "write_dtd_notation", rxml_writer_write_dtd_notation, 3); rb_define_method(cXMLWriter, "end_dtd", rxml_writer_end_dtd, 0); rb_define_method(cXMLWriter, "end_dtd_entity", rxml_writer_end_dtd_entity, 0); rb_define_method(cXMLWriter, "end_dtd_attlist", rxml_writer_end_dtd_attlist, 0); rb_define_method(cXMLWriter, "end_dtd_element", rxml_writer_end_dtd_element, 0); /* tag by parts */ rb_define_method(cXMLWriter, "write_raw", rxml_writer_write_raw, 1); rb_define_method(cXMLWriter, "write_string", rxml_writer_write_string, 1); rb_define_method(cXMLWriter, "start_cdata", rxml_writer_start_cdata, 0); rb_define_method(cXMLWriter, "end_cdata", rxml_writer_end_cdata, 0); rb_define_method(cXMLWriter, "start_attribute", rxml_writer_start_attribute, 1); rb_define_method(cXMLWriter, "start_attribute_ns", rxml_writer_start_attribute_ns, -1); rb_define_method(cXMLWriter, "end_attribute", rxml_writer_end_attribute, 0); rb_define_method(cXMLWriter, "start_element", rxml_writer_start_element, 1); rb_define_method(cXMLWriter, "start_element_ns", rxml_writer_start_element_ns, -1); rb_define_method(cXMLWriter, "end_element", rxml_writer_end_element, 0); rb_define_method(cXMLWriter, "full_end_element", rxml_writer_full_end_element, 0); rb_define_method(cXMLWriter, "start_document", rxml_writer_start_document, -1); rb_define_method(cXMLWriter, "end_document", rxml_writer_end_document, 0); #if LIBXML_VERSION >= 20607 rb_define_method(cXMLWriter, "start_comment", rxml_writer_start_comment, 0); rb_define_method(cXMLWriter, "end_comment", rxml_writer_end_comment, 0); #endif /* LIBXML_VERSION >= 20607 */ rb_define_method(cXMLWriter, "start_pi", rxml_writer_start_pi, 1); rb_define_method(cXMLWriter, "end_pi", rxml_writer_end_pi, 0); /* full tag at once */ rb_define_method(cXMLWriter, "write_attribute", rxml_writer_write_attribute, 2); rb_define_method(cXMLWriter, "write_attribute_ns", rxml_writer_write_attribute_ns, -1); rb_define_method(cXMLWriter, "write_comment", rxml_writer_write_comment, 1); rb_define_method(cXMLWriter, "write_cdata", rxml_writer_write_cdata, 1); rb_define_method(cXMLWriter, "write_element", rxml_writer_write_element, -1); rb_define_method(cXMLWriter, "write_element_ns", rxml_writer_write_element_ns, -1); rb_define_method(cXMLWriter, "write_pi", rxml_writer_write_pi, 2); rb_define_method(cXMLWriter, "result", rxml_writer_result, 0); rb_undef_method(CLASS_OF(cXMLWriter), "new"); #endif } libxml-ruby-3.2.1/ext/libxml/ruby_xml_attributes.c0000644000004100000410000001527013760147770022376 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ /* * Document-class: LibXML::XML::Attributes * * Provides access to an element's attributes (XML::Attr). * * Basic Usage: * require 'test_helper' * * doc = XML::Document.new() * attributes = doc.root.attributes * * attributes.each do |attribute| * .. * end * * attributes['foo'] = 'bar' * attribute = attributes.get_attribute['foo'] * attribute.value == 'foo' * * To access a namespaced attribute: * * XLINK_URI = 'http://www.w3.org/1999/xlink' * * attribute = attributes.get_attribute_ns(XLINK_URI, 'title') * attribute.value = 'My title' */ #include "ruby_libxml.h" #include "ruby_xml_attributes.h" VALUE cXMLAttributes; void rxml_attributes_mark(xmlNodePtr xnode) { rxml_node_mark(xnode); } /* * Creates a new attributes instance. Not exposed to ruby. */ VALUE rxml_attributes_new(xmlNodePtr xnode) { return Data_Wrap_Struct(cXMLAttributes, rxml_attributes_mark, NULL, xnode); } /* * call-seq: * attributes.node -> XML::Node * * Return the node that owns this attributes list. * * doc.root.attributes.node == doc.root */ VALUE rxml_attributes_node_get(VALUE self) { xmlNodePtr xnode; Data_Get_Struct(self, xmlNode, xnode); return rxml_node_wrap(xnode); } /* * call-seq: * attributes.get_attribute("name") -> (XML::Attr | XML::AtrrDecl) * * Returns the specified attribute. If the attribute does not * exist but the document has an associated DTD that defines * a default value for the attribute, then a XML::AttrDecl is * returned. * * name: The name of the attribute, not including a namespace. * * doc.root.attributes.get_attribute("foo") */ static VALUE rxml_attributes_get_attribute(VALUE self, VALUE name) { xmlNodePtr xnode; xmlAttrPtr xattr; name = rb_obj_as_string(name); Data_Get_Struct(self, xmlNode, xnode); xattr = xmlHasProp(xnode, (xmlChar*) StringValuePtr(name)); if (!xattr) return Qnil; else if (xattr->type == XML_ATTRIBUTE_DECL) return rxml_attr_decl_wrap((xmlAttributePtr)xattr); else return rxml_attr_wrap(xattr); } /* * call-seq: * attributes.get_attribute_ns("namespace", "name") -> (XML::Attr | XML::AtrrDecl) * * Returns the specified attribute. If the attribute does not * exist but the document has an associated DTD that defines * a default value for the attribute, then a XML::AttrDecl is * returned. * * namespace: The URI of the attribute's namespace. * name: The name of the attribute, not including a namespace. * * doc.root.attributes.get_attribute_ns('http://www.w3.org/1999/xlink', 'href') */ static VALUE rxml_attributes_get_attribute_ns(VALUE self, VALUE namespace, VALUE name) { xmlNodePtr xnode; xmlAttrPtr xattr; name = rb_obj_as_string(name); Data_Get_Struct(self, xmlNode, xnode); xattr = xmlHasNsProp(xnode, (xmlChar*) StringValuePtr(name), (xmlChar*) StringValuePtr(namespace)); if (!xattr) return Qnil; else if (xattr->type == XML_ATTRIBUTE_DECL) return rxml_attr_decl_wrap((xmlAttributePtr)xattr); else return rxml_attr_wrap(xattr); } /* * call-seq: * attributes["name"] -> String * * Fetches an attribute value. If you want to access the underlying * Attribute itself use get_attribute. * * name: The name of the attribute, not including any namespaces. * * doc.root.attributes['att'] -> 'some value' */ VALUE rxml_attributes_attribute_get(VALUE self, VALUE name) { VALUE xattr = rxml_attributes_get_attribute(self, name); if (NIL_P(xattr)) return Qnil; else return rxml_attr_value_get(xattr); } /* * call-seq: * attributes["name"] = "value" * * Sets an attribute value. If you want to get the Attribute itself, * use get_attribute. * * name: The name of the attribute, not including any namespaces. * value: The new value of the namespace. * * doc.root.attributes['att'] = 'some value' */ VALUE rxml_attributes_attribute_set(VALUE self, VALUE name, VALUE value) { VALUE xattr = rxml_attributes_get_attribute(self, name); if (NIL_P(xattr)) { VALUE args[3]; args[0] = rxml_attributes_node_get(self); args[1] = name; args[2] = value; return rb_class_new_instance(sizeof(args)/sizeof(VALUE), args, cXMLAttr); } else { return rxml_attr_value_set(xattr, value); } } /* * call-seq: * attributes.each {block} -> XML::Attr * * Iterates over each attribute. * * doc.root.attributes.each {|attribute| puts attribute.name} */ static VALUE rxml_attributes_each(VALUE self) { xmlNodePtr xnode; xmlAttrPtr xattr; Data_Get_Struct(self, xmlNode, xnode); xattr = xnode->properties; while (xattr) { /* Get the next attribute while we still can - the user may remove the yielded attribute. */ xmlAttrPtr next = xattr->next; VALUE attr = rxml_attr_wrap(xattr); rb_yield(attr); xattr = next; } return self; } /* * call-seq: * attributes.length -> Integer * * Returns the number of attributes. * * doc.root.attributes.length */ static VALUE rxml_attributes_length(VALUE self) { int length = 0; xmlNodePtr xnode; xmlAttrPtr xattr; Data_Get_Struct(self, xmlNode, xnode); xattr = xnode->properties; while (xattr) { length++; xattr = xattr->next; } return INT2NUM(length); } /* * call-seq: * attributes.first -> XML::Attr * * Returns the first attribute. * * doc.root.attributes.first */ static VALUE rxml_attributes_first(VALUE self) { xmlNodePtr xnode; Data_Get_Struct(self, xmlNode, xnode); if (xnode->type == XML_ELEMENT_NODE) { xmlAttrPtr xattr = xnode->properties; if (xattr) { return rxml_attr_wrap(xattr); } } return Qnil; } void rxml_init_attributes(void) { cXMLAttributes = rb_define_class_under(mXML, "Attributes", rb_cObject); rb_include_module(cXMLAttributes, rb_mEnumerable); rb_define_method(cXMLAttributes, "node", rxml_attributes_node_get, 0); rb_define_method(cXMLAttributes, "get_attribute", rxml_attributes_get_attribute, 1); rb_define_method(cXMLAttributes, "get_attribute_ns", rxml_attributes_get_attribute_ns, 2); rb_define_method(cXMLAttributes, "[]", rxml_attributes_attribute_get, 1); rb_define_method(cXMLAttributes, "[]=", rxml_attributes_attribute_set, 2); rb_define_method(cXMLAttributes, "each", rxml_attributes_each, 0); rb_define_method(cXMLAttributes, "length", rxml_attributes_length, 0); rb_define_method(cXMLAttributes, "first", rxml_attributes_first, 0); } libxml-ruby-3.2.1/ext/libxml/libxml.c0000644000004100000410000000370413760147770017555 0ustar www-datawww-data#include "ruby_libxml.h" #if RUBY_INTERN_H #include #else #include #endif VALUE mLibXML; static void rxml_init_memory(void) { /* Disable for now - broke attributes. xmlGcMemSetup( (xmlFreeFunc)ruby_xfree, (xmlMallocFunc)ruby_xmalloc, (xmlMallocFunc)ruby_xmalloc, (xmlReallocFunc)ruby_xrealloc, (xmlStrdupFunc)ruby_strdup );*/ } void Init_libxml_ruby(void) { /* The libxml gem provides Ruby language bindings for GNOME's Libxml2 * XML toolkit. To get started you may: * * require 'test_helper' * document = XML::Document.new * * However, when creating an application or library you plan to * redistribute, it is best to not add the LibXML module to the global * namespace, in which case you can either write your code like this: * * require 'libxml' * document = LibXML::XML::Document.new * * Refer to the README file to get started and the LICENSE file for * copyright and distribution information. */ // Seutp for threading. http://xmlsoft.org/threads.html xmlInitParser(); mLibXML = rb_define_module("LibXML"); rxml_init_memory(); rxml_init_xml(); rxml_init_io(); rxml_init_error(); rxml_init_encoding(); rxml_init_parser(); rxml_init_parser_context(); rxml_init_parser_options(); rxml_init_node(); rxml_init_attributes(); rxml_init_attr(); rxml_init_attr_decl(); rxml_init_document(); rxml_init_namespaces(); rxml_init_namespace(); rxml_init_sax_parser(); rxml_init_sax2_handler(); rxml_init_xinclude(); rxml_init_xpath(); rxml_init_xpath_object(); rxml_init_xpath_context(); rxml_init_xpath_expression(); rxml_init_xpointer(); rxml_init_html_parser(); rxml_init_html_parser_options(); rxml_init_html_parser_context(); rxml_init_input_callbacks(); rxml_init_dtd(); rxml_init_schema(); rxml_init_relaxng(); rxml_init_reader(); rxml_init_writer(); } libxml-ruby-3.2.1/ext/libxml/extconf.h0000644000004100000410000000005313760147770017733 0ustar www-datawww-data#ifndef EXTCONF_H #define EXTCONF_H #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_xpointer.c0000644000004100000410000000527313760147770022062 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include "ruby_libxml.h" #include "ruby_xml_xpointer.h" VALUE cXMLXPointer; /* * Document-class: LibXML::XML::XPointer * * The XML::Pointer class provides a standards based API for searching an xml document. * XPointer is based on the XML Path Language (XML::XPath) and is documented * at http://www.w3.org/TR/WD-xptr. */ static VALUE rxml_xpointer_point(VALUE class, VALUE rnode, VALUE xptr_str) { #ifdef LIBXML_XPTR_ENABLED xmlNodePtr xnode; xmlXPathContextPtr xctxt; xmlXPathObjectPtr xpop; VALUE context; VALUE result; VALUE argv[1]; Check_Type(xptr_str, T_STRING); if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse) rb_raise(rb_eTypeError, "require an XML::Node object"); Data_Get_Struct(rnode, xmlNode, xnode); argv[0] = rb_funcall(rnode, rb_intern("doc"), 0); context = rb_class_new_instance(1, argv, cXMLXPathContext); Data_Get_Struct(context, xmlXPathContext, xctxt); xpop = xmlXPtrEval((xmlChar*)StringValuePtr(xptr_str), xctxt); if (!xpop) rxml_raise(&xmlLastError); result = rxml_xpath_object_wrap(xnode->doc, xpop); rb_iv_set(result, "@context", context); return(result); #else rb_warn("libxml was compiled without XPointer support"); return (Qfalse); #endif } VALUE rxml_xpointer_point2(VALUE node, VALUE xptr_str) { return (rxml_xpointer_point(cXMLXPointer, node, xptr_str)); } /* * call-seq: * XML::XPointer.range(start_node, end_node) -> xpath * * Create an xpath representing the range between the supplied * start and end node. */ static VALUE rxml_xpointer_range(VALUE class, VALUE rstart, VALUE rend) { #ifdef LIBXML_XPTR_ENABLED xmlNodePtr start, end; VALUE rxxp; xmlXPathObjectPtr xpath; if (rb_obj_is_kind_of(rstart, cXMLNode) == Qfalse) rb_raise(rb_eTypeError, "require an XML::Node object as a starting point"); if (rb_obj_is_kind_of(rend, cXMLNode) == Qfalse) rb_raise(rb_eTypeError, "require an XML::Node object as an ending point"); Data_Get_Struct(rstart, xmlNode, start); if (start == NULL) return(Qnil); Data_Get_Struct(rend, xmlNode, end); if (end == NULL) return(Qnil); xpath = xmlXPtrNewRangeNodes(start, end); if (xpath == NULL) rb_fatal("You shouldn't be able to have this happen"); rxxp = rxml_xpath_object_wrap(start->doc, xpath); return(rxxp); #else rb_warn("libxml was compiled without XPointer support"); return (Qfalse); #endif } void rxml_init_xpointer(void) { cXMLXPointer = rb_define_class_under(mXML, "XPointer", rb_cObject); rb_define_singleton_method(cXMLXPointer, "range", rxml_xpointer_range, 2); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_node.h0000644000004100000410000000057513760147770021144 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_NODE__ #define __RXML_NODE__ extern VALUE cXMLNode; void rxml_init_node(void); void rxml_node_mark(xmlNodePtr xnode); VALUE rxml_node_wrap(xmlNodePtr xnode); void rxml_node_manage(xmlNodePtr xnode, VALUE node); void rxml_node_unmanage(xmlNodePtr xnode, VALUE node); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_attr_decl.c0000644000004100000410000000724013760147770022147 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ /* * Document-class: LibXML::XML::AttrDecl * * At attribute declaration is used in XML::Dtds to define * what attributes are allowed on an element. An attribute * declaration defines an attribues name, data type and default * value (if any). */ #include "ruby_libxml.h" VALUE cXMLAttrDecl; void rxml_attr_decl_mark(xmlAttributePtr xattr) { rxml_node_mark((xmlNodePtr) xattr); } VALUE rxml_attr_decl_wrap(xmlAttributePtr xattr) { return Data_Wrap_Struct(cXMLAttrDecl, rxml_attr_decl_mark, NULL, xattr); } /* * call-seq: * attr_decl.doc -> XML::Document * * Returns this attribute declaration's document. */ static VALUE rxml_attr_decl_doc_get(VALUE self) { xmlAttributePtr xattr; Data_Get_Struct(self, xmlAttribute, xattr); if (xattr->doc == NULL) return Qnil; else return rxml_document_wrap(xattr->doc); } /* * call-seq: * attr_decl.name -> "name" * * Obtain this attribute declaration's name. */ static VALUE rxml_attr_decl_name_get(VALUE self) { xmlAttributePtr xattr; Data_Get_Struct(self, xmlAttribute, xattr); if (xattr->name == NULL) return Qnil; else return rxml_new_cstr( xattr->name, xattr->doc->encoding); } /* * call-seq: * attr_decl.next -> XML::AttrDecl * * Obtain the next attribute declaration. */ static VALUE rxml_attr_decl_next_get(VALUE self) { xmlAttributePtr xattr; Data_Get_Struct(self, xmlAttribute, xattr); if (xattr->next == NULL) return Qnil; else return rxml_attr_decl_wrap((xmlAttributePtr)xattr->next); } /* * call-seq: * attr_decl.type -> num * * Obtain this attribute declaration's type node type. */ static VALUE rxml_attr_decl_node_type(VALUE self) { xmlAttrPtr xattr; Data_Get_Struct(self, xmlAttr, xattr); return INT2NUM(xattr->type); } /* * call-seq: * attr_decl.parent -> XML::Dtd * * Obtain this attribute declaration's parent which * is an instance of a XML::DTD. */ static VALUE rxml_attr_decl_parent_get(VALUE self) { xmlAttributePtr xattr; Data_Get_Struct(self, xmlAttribute, xattr); if (xattr->parent == NULL) return Qnil; else return rxml_dtd_wrap(xattr->parent); } /* * call-seq: * attr_decl.prev -> (XML::AttrDecl | XML::ElementDecl) * * Obtain the previous attribute declaration or the owning * element declration (not implemented). */ static VALUE rxml_attr_decl_prev_get(VALUE self) { xmlAttributePtr xattr; Data_Get_Struct(self, xmlAttribute, xattr); if (xattr->prev == NULL) return Qnil; else return rxml_attr_decl_wrap((xmlAttributePtr)xattr->prev); } /* * call-seq: * attr_decl.value -> "value" * * Obtain the default value of this attribute declaration. */ VALUE rxml_attr_decl_value_get(VALUE self) { xmlAttributePtr xattr; Data_Get_Struct(self, xmlAttribute, xattr); if (xattr->defaultValue) return rxml_new_cstr(xattr->defaultValue, NULL); else return Qnil; } void rxml_init_attr_decl(void) { cXMLAttrDecl = rb_define_class_under(mXML, "AttrDecl", rb_cObject); rb_define_method(cXMLAttrDecl, "doc", rxml_attr_decl_doc_get, 0); rb_define_method(cXMLAttrDecl, "name", rxml_attr_decl_name_get, 0); rb_define_method(cXMLAttrDecl, "next", rxml_attr_decl_next_get, 0); rb_define_method(cXMLAttrDecl, "node_type", rxml_attr_decl_node_type, 0); rb_define_method(cXMLAttrDecl, "parent", rxml_attr_decl_parent_get, 0); rb_define_method(cXMLAttrDecl, "prev", rxml_attr_decl_prev_get, 0); rb_define_method(cXMLAttrDecl, "value", rxml_attr_decl_value_get, 0); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_schema_type.h0000644000004100000410000000030113760147770022503 0ustar www-datawww-data#ifndef __RXML_SCHEMA_TYPE__ #define __RXML_SCHEMA_TYPE__ extern VALUE cXMLSchemaType; VALUE rxml_wrap_schema_type(xmlSchemaTypePtr xtype); void rxml_init_schema_type(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_io.h0000644000004100000410000000044013760147770020615 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_IO__ #define __RXML_IO__ int rxml_read_callback(void *context, char *buffer, int len); int rxml_write_callback(VALUE io, const char *buffer, int len); void rxml_init_io(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_parser_options.h0000644000004100000410000000041113760147770023253 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_PARSER_OPTIONS__ #define __RXML_PARSER_OPTIONS__ #define MAX_LIBXML_FEATURES_LEN 50 extern VALUE mXMLParserOptions; void rxml_init_parser_options(); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_xpath.h0000644000004100000410000000046713760147770021343 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_XPATH__ #define __RXML_XPATH__ extern VALUE mXPath; void rxml_init_xpath(void); VALUE rxml_xpath_to_value(xmlXPathContextPtr, xmlXPathObjectPtr); xmlXPathObjectPtr rxml_xpath_from_value(VALUE); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_input_cbg.c0000644000004100000410000001056213760147770022161 0ustar www-datawww-data/* Author: Martin Povolny (xpovolny@fi.muni.cz) */ #include "ruby_libxml.h" #include "ruby_xml_input_cbg.h" /* Document-class: LibXML::XML::InputCallbacks * * Support for adding custom scheme handlers. */ static ic_scheme *first_scheme = 0; int ic_match(char const *filename) { ic_scheme *scheme; //fprintf( stderr, "ic_match: %s\n", filename ); scheme = first_scheme; while (0 != scheme) { if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST scheme->scheme_name, scheme->name_len)) { return 1; } scheme = scheme->next_scheme; } return 0; } void* ic_open(char const *filename) { ic_doc_context *ic_doc; ic_scheme *scheme; VALUE res; scheme = first_scheme; while (0 != scheme) { if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST scheme->scheme_name, scheme->name_len)) { ic_doc = (ic_doc_context*) malloc(sizeof(ic_doc_context)); res = rb_funcall(scheme->class, rb_intern("document_query"), 1, rb_str_new2(filename)); ic_doc->buffer = strdup(StringValuePtr(res)); ic_doc->bpos = ic_doc->buffer; ic_doc->remaining = (int)strlen(ic_doc->buffer); return ic_doc; } scheme = scheme->next_scheme; } return 0; } int ic_read(void *context, char *buffer, int len) { ic_doc_context *ic_doc; int ret_len; ic_doc = (ic_doc_context*) context; if (len >= ic_doc->remaining) { ret_len = ic_doc->remaining; } else { ret_len = len; } ic_doc->remaining -= ret_len; strncpy(buffer, ic_doc->bpos, ret_len); ic_doc->bpos += ret_len; return ret_len; } int ic_close(void *context) { ruby_xfree(((ic_doc_context*) context)->buffer); ruby_xfree(context); return 1; } /* * call-seq: * register * * Register a new set of I/O callback for handling parser input. */ static VALUE input_callbacks_register_input_callbacks() { xmlRegisterInputCallbacks(ic_match, ic_open, ic_read, ic_close); return (Qtrue); } /* * call-seq: * add_scheme * * No documentation available. */ static VALUE input_callbacks_add_scheme(VALUE self, VALUE scheme_name, VALUE class) { ic_scheme *scheme; Check_Type(scheme_name, T_STRING); scheme = (ic_scheme*) malloc(sizeof(ic_scheme)); scheme->next_scheme = 0; scheme->scheme_name = strdup(StringValuePtr(scheme_name)); /* TODO alloc, dealloc */ scheme->name_len = (int)strlen(scheme->scheme_name); scheme->class = class; /* TODO alloc, dealloc */ //fprintf( stderr, "registered: %s, %d, %s\n", scheme->scheme_name, scheme->name_len, scheme->class ); if (0 == first_scheme) first_scheme = scheme; else { ic_scheme *pos; pos = first_scheme; while (0 != pos->next_scheme) pos = pos->next_scheme; pos->next_scheme = scheme; } return (Qtrue); } /* * call-seq: * remove_scheme * * No documentation available. */ static VALUE input_callbacks_remove_scheme(VALUE self, VALUE scheme_name) { char *name; ic_scheme *save_scheme, *scheme; Check_Type(scheme_name, T_STRING); name = StringValuePtr(scheme_name); if (0 == first_scheme) return Qfalse; if (!strncmp(name, first_scheme->scheme_name, first_scheme->name_len)) { save_scheme = first_scheme->next_scheme; ruby_xfree(first_scheme->scheme_name); ruby_xfree(first_scheme); first_scheme = save_scheme; return Qtrue; } scheme = first_scheme; while (0 != scheme->next_scheme) { if (!strncmp(name, scheme->next_scheme->scheme_name, scheme->next_scheme->name_len)) { save_scheme = scheme->next_scheme->next_scheme; ruby_xfree(scheme->next_scheme->scheme_name); ruby_xfree(scheme->next_scheme); scheme->next_scheme = save_scheme; return Qtrue; } scheme = scheme->next_scheme; } return Qfalse; } void rxml_init_input_callbacks(void) { VALUE cInputCallbacks; cInputCallbacks = rb_define_class_under(mXML, "InputCallbacks", rb_cObject); /* Class Methods */ rb_define_singleton_method(cInputCallbacks, "register", input_callbacks_register_input_callbacks, 0); rb_define_singleton_method(cInputCallbacks, "add_scheme", input_callbacks_add_scheme, 2); rb_define_singleton_method(cInputCallbacks, "remove_scheme", input_callbacks_remove_scheme, 1); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_error.c0000644000004100000410000022251313760147770021341 0ustar www-datawww-data#include "ruby_libxml.h" #include VALUE eXMLError; static ID CALL_METHOD; static ID ERROR_HANDLER_ID; /* * Document-class: LibXML::XML::Error * * The XML::Error class exposes libxml errors as * standard Ruby exceptions. When appropriate, * libxml-ruby will raise an exception - for example, * when parsing a non-well formed xml document. * * By default, warnings, errors and fatal errors that * libxml generates are printed to STDERR via the * XML::Error::VERBOSE_HANDLER proc. * * To disable this output you can install the quiet handler: * * XML::Error.set_handler(&XML::Error::QUIET_HANDLER) * * Get the current handler: * * proc = XML::Error.get_handler * * Install your own handler: * * XML::Error.set_handler do |error| * puts error.to_s * end * * Or remove all handlers: * * XML::Error.reset_handler */ /* * call-seq: * Error.get_error_handler * * Returns the proc that will be called when libxml generates * warning, error or fatal error messages. */ static VALUE rxml_error_get_handler() { VALUE block = rb_cvar_get(eXMLError, ERROR_HANDLER_ID); return block; } VALUE rxml_error_wrap(xmlErrorPtr xerror) { VALUE result = Qnil; if (xerror->message) result = rb_exc_new2(eXMLError, xerror->message); else result = rb_class_new_instance(0, NULL, eXMLError); rb_iv_set(result, "@domain", INT2NUM(xerror->domain)); rb_iv_set(result, "@code", INT2NUM(xerror->code)); rb_iv_set(result, "@level", INT2NUM(xerror->level)); if (xerror->file) rb_iv_set(result, "@file", rb_str_new2(xerror->file)); if (xerror->line) rb_iv_set(result, "@line", INT2NUM(xerror->line)); if (xerror->str1) rb_iv_set(result, "@str1", rb_str_new2(xerror->str1)); if (xerror->str2) rb_iv_set(result, "@str2", rb_str_new2(xerror->str2)); if (xerror->str3) rb_iv_set(result, "@str3", rb_str_new2(xerror->str3)); rb_iv_set(result, "@int1", INT2NUM(xerror->int1)); rb_iv_set(result, "@int2", INT2NUM(xerror->int2)); if (xerror->node) { /* Returning the original node is too dangerous because its parent document is never returned to Ruby. So return a copy of the node, which does not belong to any document, and can free itself when Ruby calls its free method. Note we just copy the node, and don't bother with the overhead of a recursive query. */ xmlNodePtr xNode = xmlCopyNode((const xmlNodePtr)xerror->node, 2); VALUE node = rxml_node_wrap(xNode); rb_iv_set(result, "@node", node); } return result; } /* Hook that receives xml error message */ static void structuredErrorFunc(void *userData, xmlErrorPtr xerror) { VALUE error = rxml_error_wrap(xerror); /* Wrap error up as Ruby object and send it off to ruby */ VALUE block = rxml_error_get_handler(); /* Now call global handler */ if (block != Qnil) { rb_funcall(block, CALL_METHOD, 1, error); } } static void rxml_set_handler(VALUE self, VALUE block) { #ifdef RB_CVAR_SET_4ARGS rb_cvar_set(self, ERROR_HANDLER_ID, block, 0); #else rb_cvar_set(self, ERROR_HANDLER_ID, block); #endif /* Intercept libxml error handlers */ xmlSetStructuredErrorFunc(NULL, structuredErrorFunc); } /* * call-seq: * Error.set_error_handler {|error| ... } * * Registers a block that will be called with an instance of * XML::Error when libxml generates warning, error or fatal * error messages. */ static VALUE rxml_error_set_handler(VALUE self) { VALUE block; if (rb_block_given_p() == Qfalse) rb_raise(rb_eRuntimeError, "No block given"); block = rb_block_proc(); /* Embed the block within the Error class to avoid it to be collected. Previous handler will be overwritten if it exists. */ rxml_set_handler(self, block); return self; } /* * call-seq: * Error.reset_error_handler * * Removes the current error handler. */ static VALUE rxml_error_reset_handler(VALUE self) { rxml_set_handler(self, Qnil); return self; } NORETURN(void rxml_raise(xmlErrorPtr xerror)) { /* Wrap error up as Ruby object and send it off to ruby */ VALUE error = rxml_error_wrap(xerror); rb_exc_raise(error); } void rxml_init_error() { CALL_METHOD = rb_intern("call"); ERROR_HANDLER_ID = rb_intern("@@__error_handler_callback__"); /* Error class */ eXMLError = rb_define_class_under(mXML, "Error", rb_eStandardError); rb_define_singleton_method(eXMLError, "get_handler", rxml_error_get_handler, 0); rb_define_singleton_method(eXMLError, "set_handler", rxml_error_set_handler, 0); rb_define_singleton_method(eXMLError, "reset_handler", rxml_error_reset_handler, 0); /* Ruby callback to receive errors - set it to nil by default. */ rxml_set_handler(eXMLError, Qnil); /* Error attributes */ rb_define_attr(eXMLError, "level", 1, 0); rb_define_attr(eXMLError, "domain", 1, 0); rb_define_attr(eXMLError, "code", 1, 0); rb_define_attr(eXMLError, "file", 1, 0); rb_define_attr(eXMLError, "line", 1, 0); rb_define_attr(eXMLError, "str1", 1, 0); rb_define_attr(eXMLError, "str2", 1, 0); rb_define_attr(eXMLError, "str3", 1, 0); rb_define_attr(eXMLError, "int1", 1, 0); rb_define_attr(eXMLError, "int2", 1, 0); rb_define_attr(eXMLError, "ctxt", 1, 0); rb_define_attr(eXMLError, "node", 1, 0); /* xml error levels */ rb_define_const(eXMLError, "NONE", INT2NUM(XML_ERR_NONE)); rb_define_const(eXMLError, "WARNING", INT2NUM(XML_ERR_WARNING)); rb_define_const(eXMLError, "ERROR", INT2NUM(XML_ERR_ERROR)); rb_define_const(eXMLError, "FATAL", INT2NUM(XML_ERR_FATAL)); /* xml error domains */ rb_define_const(eXMLError, "NO_ERROR", INT2NUM(XML_FROM_NONE)); rb_define_const(eXMLError, "PARSER", INT2NUM(XML_FROM_PARSER)); rb_define_const(eXMLError, "TREE", INT2NUM(XML_FROM_TREE)); rb_define_const(eXMLError, "NAMESPACE", INT2NUM(XML_FROM_NAMESPACE)); rb_define_const(eXMLError, "DTD", INT2NUM(XML_FROM_DTD)); rb_define_const(eXMLError, "HTML", INT2NUM(XML_FROM_HTML)); rb_define_const(eXMLError, "MEMORY", INT2NUM(XML_FROM_MEMORY)); rb_define_const(eXMLError, "OUTPUT", INT2NUM(XML_FROM_OUTPUT)); rb_define_const(eXMLError, "IO", INT2NUM(XML_FROM_IO)); rb_define_const(eXMLError, "FTP", INT2NUM(XML_FROM_FTP)); rb_define_const(eXMLError, "HTTP", INT2NUM(XML_FROM_HTTP)); rb_define_const(eXMLError, "XINCLUDE", INT2NUM(XML_FROM_XINCLUDE)); rb_define_const(eXMLError, "XPATH", INT2NUM(XML_FROM_XPATH)); rb_define_const(eXMLError, "XPOINTER", INT2NUM(XML_FROM_XPOINTER)); rb_define_const(eXMLError, "REGEXP", INT2NUM(XML_FROM_REGEXP)); rb_define_const(eXMLError, "DATATYPE", INT2NUM(XML_FROM_DATATYPE)); rb_define_const(eXMLError, "SCHEMASP", INT2NUM(XML_FROM_SCHEMASP)); rb_define_const(eXMLError, "SCHEMASV", INT2NUM(XML_FROM_SCHEMASV)); rb_define_const(eXMLError, "RELAXNGP", INT2NUM(XML_FROM_RELAXNGP)); rb_define_const(eXMLError, "RELAXNGV", INT2NUM(XML_FROM_RELAXNGV)); rb_define_const(eXMLError, "CATALOG", INT2NUM(XML_FROM_CATALOG)); rb_define_const(eXMLError, "C14N", INT2NUM(XML_FROM_C14N)); rb_define_const(eXMLError, "XSLT", INT2NUM(XML_FROM_XSLT)); rb_define_const(eXMLError, "VALID", INT2NUM(XML_FROM_VALID)); rb_define_const(eXMLError, "CHECK", INT2NUM(XML_FROM_CHECK)); rb_define_const(eXMLError, "WRITER", INT2NUM(XML_FROM_WRITER)); #if LIBXML_VERSION >= 20621 rb_define_const(eXMLError, "MODULE", INT2NUM(XML_FROM_MODULE)); #endif #if LIBXML_VERSION >= 20632 rb_define_const(eXMLError, "I18N", INT2NUM(XML_FROM_I18N)); rb_define_const(eXMLError, "SCHEMATRONV", INT2NUM(XML_FROM_SCHEMATRONV)); #endif /* errors */ rb_define_const(eXMLError, "OK", INT2NUM(XML_ERR_OK)); rb_define_const(eXMLError, "INTERNAL_ERROR", INT2NUM(XML_ERR_INTERNAL_ERROR)); rb_define_const(eXMLError, "NO_MEMORY", INT2NUM(XML_ERR_NO_MEMORY)); rb_define_const(eXMLError, "DOCUMENT_START", INT2NUM(XML_ERR_DOCUMENT_START)); rb_define_const(eXMLError, "DOCUMENT_EMPTY", INT2NUM(XML_ERR_DOCUMENT_EMPTY)); rb_define_const(eXMLError, "DOCUMENT_END", INT2NUM(XML_ERR_DOCUMENT_END)); rb_define_const(eXMLError, "INVALID_HEX_CHARREF", INT2NUM(XML_ERR_INVALID_HEX_CHARREF)); rb_define_const(eXMLError, "INVALID_DEC_CHARREF", INT2NUM(XML_ERR_INVALID_DEC_CHARREF)); rb_define_const(eXMLError, "INVALID_CHARREF", INT2NUM(XML_ERR_INVALID_CHARREF)); rb_define_const(eXMLError, "INVALID_CHAR", INT2NUM(XML_ERR_INVALID_CHAR)); rb_define_const(eXMLError, "CHARREF_AT_EOF", INT2NUM(XML_ERR_CHARREF_AT_EOF)); rb_define_const(eXMLError, "CHARREF_IN_PROLOG", INT2NUM(XML_ERR_CHARREF_IN_PROLOG)); rb_define_const(eXMLError, "CHARREF_IN_EPILOG", INT2NUM(XML_ERR_CHARREF_IN_EPILOG)); rb_define_const(eXMLError, "CHARREF_IN_DTD", INT2NUM(XML_ERR_CHARREF_IN_DTD)); rb_define_const(eXMLError, "ENTITYREF_AT_EOF", INT2NUM(XML_ERR_ENTITYREF_AT_EOF)); rb_define_const(eXMLError, "ENTITYREF_IN_PROLOG", INT2NUM(XML_ERR_ENTITYREF_IN_PROLOG)); rb_define_const(eXMLError, "ENTITYREF_IN_EPILOG", INT2NUM(XML_ERR_ENTITYREF_IN_EPILOG)); rb_define_const(eXMLError, "ENTITYREF_IN_DTD", INT2NUM(XML_ERR_ENTITYREF_IN_DTD)); rb_define_const(eXMLError, "PEREF_AT_EOF", INT2NUM(XML_ERR_PEREF_AT_EOF)); rb_define_const(eXMLError, "PEREF_IN_PROLOG", INT2NUM(XML_ERR_PEREF_IN_PROLOG)); rb_define_const(eXMLError, "PEREF_IN_EPILOG",INT2NUM(XML_ERR_PEREF_IN_EPILOG)); rb_define_const(eXMLError, "PEREF_IN_INT_SUBSET", INT2NUM(XML_ERR_PEREF_IN_INT_SUBSET)); rb_define_const(eXMLError, "ENTITYREF_NO_NAME", INT2NUM(XML_ERR_ENTITYREF_NO_NAME)); rb_define_const(eXMLError, "ENTITYREF_SEMICOL_MISSING", INT2NUM(XML_ERR_ENTITYREF_SEMICOL_MISSING)); rb_define_const(eXMLError, "PEREF_NO_NAME", INT2NUM(XML_ERR_PEREF_NO_NAME)); rb_define_const(eXMLError, "PEREF_SEMICOL_MISSING", INT2NUM(XML_ERR_PEREF_SEMICOL_MISSING)); rb_define_const(eXMLError, "UNDECLARED_ENTITY", INT2NUM(XML_ERR_UNDECLARED_ENTITY)); rb_define_const(eXMLError, "XML_WAR_UNDECLARED_ENTITY", INT2NUM(XML_WAR_UNDECLARED_ENTITY)); rb_define_const(eXMLError, "UNPARSED_ENTITY", INT2NUM(XML_ERR_UNPARSED_ENTITY)); rb_define_const(eXMLError, "ENTITY_IS_EXTERNAL", INT2NUM(XML_ERR_ENTITY_IS_EXTERNAL)); rb_define_const(eXMLError, "ENTITY_IS_PARAMETER", INT2NUM(XML_ERR_ENTITY_IS_PARAMETER)); rb_define_const(eXMLError, "UNKNOWN_ENCODING", INT2NUM(XML_ERR_UNKNOWN_ENCODING)); rb_define_const(eXMLError, "UNSUPPORTED_ENCODING", INT2NUM(XML_ERR_UNSUPPORTED_ENCODING)); rb_define_const(eXMLError, "STRING_NOT_STARTED", INT2NUM(XML_ERR_STRING_NOT_STARTED)); rb_define_const(eXMLError, "STRING_NOT_CLOSED", INT2NUM(XML_ERR_STRING_NOT_CLOSED)); rb_define_const(eXMLError, "NS_DECL_ERROR", INT2NUM(XML_ERR_NS_DECL_ERROR)); rb_define_const(eXMLError, "ENTITY_NOT_STARTED", INT2NUM(XML_ERR_ENTITY_NOT_STARTED)); rb_define_const(eXMLError, "ENTITY_NOT_FINISHED", INT2NUM(XML_ERR_ENTITY_NOT_FINISHED)); rb_define_const(eXMLError, "LT_IN_ATTRIBUTE", INT2NUM(XML_ERR_LT_IN_ATTRIBUTE)); rb_define_const(eXMLError, "ATTRIBUTE_NOT_STARTED", INT2NUM(XML_ERR_ATTRIBUTE_NOT_STARTED)); rb_define_const(eXMLError, "ATTRIBUTE_NOT_FINISHED", INT2NUM(XML_ERR_ATTRIBUTE_NOT_FINISHED)); rb_define_const(eXMLError, "ATTRIBUTE_WITHOUT_VALUE", INT2NUM(XML_ERR_ATTRIBUTE_WITHOUT_VALUE)); rb_define_const(eXMLError, "ATTRIBUTE_REDEFINED", INT2NUM(XML_ERR_ATTRIBUTE_REDEFINED)); rb_define_const(eXMLError, "LITERAL_NOT_STARTED", INT2NUM(XML_ERR_LITERAL_NOT_STARTED)); rb_define_const(eXMLError, "LITERAL_NOT_FINISHED", INT2NUM(XML_ERR_LITERAL_NOT_FINISHED)); rb_define_const(eXMLError, "COMMENT_NOT_FINISHED", INT2NUM(XML_ERR_COMMENT_NOT_FINISHED)); rb_define_const(eXMLError, "PI_NOT_STARTED", INT2NUM(XML_ERR_PI_NOT_STARTED)); rb_define_const(eXMLError, "PI_NOT_FINISHED", INT2NUM(XML_ERR_PI_NOT_FINISHED)); rb_define_const(eXMLError, "NOTATION_NOT_STARTED", INT2NUM(XML_ERR_NOTATION_NOT_STARTED)); rb_define_const(eXMLError, "NOTATION_NOT_FINISHED", INT2NUM(XML_ERR_NOTATION_NOT_FINISHED)); rb_define_const(eXMLError, "ATTLIST_NOT_STARTED", INT2NUM(XML_ERR_ATTLIST_NOT_STARTED)); rb_define_const(eXMLError, "ATTLIST_NOT_FINISHED", INT2NUM(XML_ERR_ATTLIST_NOT_FINISHED)); rb_define_const(eXMLError, "MIXED_NOT_STARTED", INT2NUM(XML_ERR_MIXED_NOT_STARTED)); rb_define_const(eXMLError, "MIXED_NOT_FINISHED", INT2NUM(XML_ERR_MIXED_NOT_FINISHED)); rb_define_const(eXMLError, "ELEMCONTENT_NOT_STARTED", INT2NUM(XML_ERR_ELEMCONTENT_NOT_STARTED)); rb_define_const(eXMLError, "ELEMCONTENT_NOT_FINISHED", INT2NUM(XML_ERR_ELEMCONTENT_NOT_FINISHED)); rb_define_const(eXMLError, "XMLDECL_NOT_STARTED", INT2NUM(XML_ERR_XMLDECL_NOT_STARTED)); rb_define_const(eXMLError, "XMLDECL_NOT_FINISHED", INT2NUM(XML_ERR_XMLDECL_NOT_FINISHED)); rb_define_const(eXMLError, "CONDSEC_NOT_STARTED", INT2NUM(XML_ERR_CONDSEC_NOT_STARTED)); rb_define_const(eXMLError, "CONDSEC_NOT_FINISHED", INT2NUM(XML_ERR_CONDSEC_NOT_FINISHED)); rb_define_const(eXMLError, "EXT_SUBSET_NOT_FINISHED", INT2NUM(XML_ERR_EXT_SUBSET_NOT_FINISHED)); rb_define_const(eXMLError, "DOCTYPE_NOT_FINISHED", INT2NUM(XML_ERR_DOCTYPE_NOT_FINISHED)); rb_define_const(eXMLError, "MISPLACED_CDATA_END", INT2NUM(XML_ERR_MISPLACED_CDATA_END)); rb_define_const(eXMLError, "CDATA_NOT_FINISHED", INT2NUM(XML_ERR_CDATA_NOT_FINISHED)); rb_define_const(eXMLError, "RESERVED_XML_NAME", INT2NUM(XML_ERR_RESERVED_XML_NAME)); rb_define_const(eXMLError, "SPACE_REQUIRED", INT2NUM(XML_ERR_SPACE_REQUIRED)); rb_define_const(eXMLError, "SEPARATOR_REQUIRED", INT2NUM(XML_ERR_SEPARATOR_REQUIRED)); rb_define_const(eXMLError, "NMTOKEN_REQUIRED", INT2NUM(XML_ERR_NMTOKEN_REQUIRED)); rb_define_const(eXMLError, "NAME_REQUIRED", INT2NUM(XML_ERR_NAME_REQUIRED)); rb_define_const(eXMLError, "PCDATA_REQUIRED", INT2NUM(XML_ERR_PCDATA_REQUIRED)); rb_define_const(eXMLError, "URI_REQUIRED", INT2NUM(XML_ERR_URI_REQUIRED)); rb_define_const(eXMLError, "PUBID_REQUIRED", INT2NUM(XML_ERR_PUBID_REQUIRED)); rb_define_const(eXMLError, "LT_REQUIRED", INT2NUM(XML_ERR_LT_REQUIRED)); rb_define_const(eXMLError, "GT_REQUIRED", INT2NUM(XML_ERR_GT_REQUIRED)); rb_define_const(eXMLError, "LTSLASH_REQUIRED", INT2NUM(XML_ERR_LTSLASH_REQUIRED)); rb_define_const(eXMLError, "EQUAL_REQUIRED", INT2NUM(XML_ERR_EQUAL_REQUIRED)); rb_define_const(eXMLError, "TAG_NAME_MISMATCH", INT2NUM(XML_ERR_TAG_NAME_MISMATCH)); rb_define_const(eXMLError, "TAG_NOT_FINISHED", INT2NUM(XML_ERR_TAG_NOT_FINISHED)); rb_define_const(eXMLError, "STANDALONE_VALUE", INT2NUM(XML_ERR_STANDALONE_VALUE)); rb_define_const(eXMLError, "ENCODING_NAME", INT2NUM(XML_ERR_ENCODING_NAME)); rb_define_const(eXMLError, "HYPHEN_IN_COMMENT", INT2NUM(XML_ERR_HYPHEN_IN_COMMENT)); rb_define_const(eXMLError, "INVALID_ENCODING", INT2NUM(XML_ERR_INVALID_ENCODING)); rb_define_const(eXMLError, "EXT_ENTITY_STANDALONE", INT2NUM(XML_ERR_EXT_ENTITY_STANDALONE)); rb_define_const(eXMLError, "CONDSEC_INVALID", INT2NUM(XML_ERR_CONDSEC_INVALID)); rb_define_const(eXMLError, "VALUE_REQUIRED", INT2NUM(XML_ERR_VALUE_REQUIRED)); rb_define_const(eXMLError, "NOT_WELL_BALANCED", INT2NUM(XML_ERR_NOT_WELL_BALANCED)); rb_define_const(eXMLError, "EXTRA_CONTENT", INT2NUM(XML_ERR_EXTRA_CONTENT)); rb_define_const(eXMLError, "ENTITY_CHAR_ERROR", INT2NUM(XML_ERR_ENTITY_CHAR_ERROR)); rb_define_const(eXMLError, "ENTITY_PE_INTERNAL", INT2NUM(XML_ERR_ENTITY_PE_INTERNAL)); rb_define_const(eXMLError, "ENTITY_LOOP", INT2NUM(XML_ERR_ENTITY_LOOP)); rb_define_const(eXMLError, "ENTITY_BOUNDARY", INT2NUM(XML_ERR_ENTITY_BOUNDARY)); rb_define_const(eXMLError, "INVALID_URI", INT2NUM(XML_ERR_INVALID_URI)); rb_define_const(eXMLError, "URI_FRAGMENT", INT2NUM(XML_ERR_URI_FRAGMENT)); rb_define_const(eXMLError, "XML_WAR_CATALOG_PI", INT2NUM(XML_WAR_CATALOG_PI)); rb_define_const(eXMLError, "NO_DTD", INT2NUM(XML_ERR_NO_DTD)); rb_define_const(eXMLError, "CONDSEC_INVALID_KEYWORD", INT2NUM(XML_ERR_CONDSEC_INVALID_KEYWORD)); rb_define_const(eXMLError, "VERSION_MISSING", INT2NUM(XML_ERR_VERSION_MISSING)); rb_define_const(eXMLError, "XML_WAR_UNKNOWN_VERSION", INT2NUM(XML_WAR_UNKNOWN_VERSION)); rb_define_const(eXMLError, "XML_WAR_LANG_VALUE", INT2NUM(XML_WAR_LANG_VALUE)); rb_define_const(eXMLError, "XML_WAR_NS_URI", INT2NUM(XML_WAR_NS_URI)); rb_define_const(eXMLError, "XML_WAR_NS_URI_RELATIVE", INT2NUM(XML_WAR_NS_URI_RELATIVE)); rb_define_const(eXMLError, "MISSING_ENCODING", INT2NUM(XML_ERR_MISSING_ENCODING)); #if LIBXML_VERSION >= 20620 rb_define_const(eXMLError, "XML_WAR_SPACE_VALUE", INT2NUM(XML_WAR_SPACE_VALUE)); rb_define_const(eXMLError, "NOT_STANDALONE", INT2NUM(XML_ERR_NOT_STANDALONE)); rb_define_const(eXMLError, "ENTITY_PROCESSING", INT2NUM(XML_ERR_ENTITY_PROCESSING)); rb_define_const(eXMLError, "NOTATION_PROCESSING", INT2NUM(XML_ERR_NOTATION_PROCESSING)); rb_define_const(eXMLError, "WAR_NS_COLUMN", INT2NUM(XML_WAR_NS_COLUMN)); rb_define_const(eXMLError, "WAR_ENTITY_REDEFINED", INT2NUM(XML_WAR_ENTITY_REDEFINED)); #endif rb_define_const(eXMLError, "NS_ERR_XML_NAMESPACE", INT2NUM(XML_NS_ERR_XML_NAMESPACE)); rb_define_const(eXMLError, "NS_ERR_UNDEFINED_NAMESPACE", INT2NUM(XML_NS_ERR_UNDEFINED_NAMESPACE)); rb_define_const(eXMLError, "NS_ERR_QNAME", INT2NUM(XML_NS_ERR_QNAME)); rb_define_const(eXMLError, "NS_ERR_ATTRIBUTE_REDEFINED", INT2NUM(XML_NS_ERR_ATTRIBUTE_REDEFINED)); #if LIBXML_VERSION >= 20620 rb_define_const(eXMLError, "NS_ERR_EMPTY", INT2NUM(XML_NS_ERR_EMPTY)); #endif #if LIBXML_VERSION >= 20700 rb_define_const(eXMLError, "NS_ERR_COLON", INT2NUM(XML_NS_ERR_COLON)); #endif rb_define_const(eXMLError, "DTD_ATTRIBUTE_DEFAULT", INT2NUM(XML_DTD_ATTRIBUTE_DEFAULT)); rb_define_const(eXMLError, "DTD_ATTRIBUTE_REDEFINED", INT2NUM(XML_DTD_ATTRIBUTE_REDEFINED)); rb_define_const(eXMLError, "DTD_ATTRIBUTE_VALUE", INT2NUM(XML_DTD_ATTRIBUTE_VALUE)); rb_define_const(eXMLError, "DTD_CONTENT_ERROR", INT2NUM(XML_DTD_CONTENT_ERROR)); rb_define_const(eXMLError, "DTD_CONTENT_MODEL", INT2NUM(XML_DTD_CONTENT_MODEL)); rb_define_const(eXMLError, "DTD_CONTENT_NOT_DETERMINIST", INT2NUM(XML_DTD_CONTENT_NOT_DETERMINIST)); rb_define_const(eXMLError, "DTD_DIFFERENT_PREFIX", INT2NUM(XML_DTD_DIFFERENT_PREFIX)); rb_define_const(eXMLError, "DTD_ELEM_DEFAULT_NAMESPACE", INT2NUM(XML_DTD_ELEM_DEFAULT_NAMESPACE)); rb_define_const(eXMLError, "DTD_ELEM_NAMESPACE", INT2NUM(XML_DTD_ELEM_NAMESPACE)); rb_define_const(eXMLError, "DTD_ELEM_REDEFINED", INT2NUM(XML_DTD_ELEM_REDEFINED)); rb_define_const(eXMLError, "DTD_EMPTY_NOTATION", INT2NUM(XML_DTD_EMPTY_NOTATION)); rb_define_const(eXMLError, "DTD_ENTITY_TYPE", INT2NUM(XML_DTD_ENTITY_TYPE)); rb_define_const(eXMLError, "DTD_ID_FIXED", INT2NUM(XML_DTD_ID_FIXED)); rb_define_const(eXMLError, "DTD_ID_REDEFINED", INT2NUM(XML_DTD_ID_REDEFINED)); rb_define_const(eXMLError, "DTD_ID_SUBSET", INT2NUM(XML_DTD_ID_SUBSET)); rb_define_const(eXMLError, "DTD_INVALID_CHILD", INT2NUM(XML_DTD_INVALID_CHILD)); rb_define_const(eXMLError, "DTD_INVALID_DEFAULT", INT2NUM(XML_DTD_INVALID_DEFAULT)); rb_define_const(eXMLError, "DTD_LOAD_ERROR", INT2NUM(XML_DTD_LOAD_ERROR)); rb_define_const(eXMLError, "DTD_MISSING_ATTRIBUTE", INT2NUM(XML_DTD_MISSING_ATTRIBUTE)); rb_define_const(eXMLError, "DTD_MIXED_CORRUPT", INT2NUM(XML_DTD_MIXED_CORRUPT)); rb_define_const(eXMLError, "DTD_MULTIPLE_ID", INT2NUM(XML_DTD_MULTIPLE_ID)); rb_define_const(eXMLError, "DTD_NO_DOC", INT2NUM(XML_DTD_NO_DOC)); rb_define_const(eXMLError, "DTD_NO_DTD", INT2NUM(XML_DTD_NO_DTD)); rb_define_const(eXMLError, "DTD_NO_ELEM_NAME", INT2NUM(XML_DTD_NO_ELEM_NAME)); rb_define_const(eXMLError, "DTD_NO_PREFIX", INT2NUM(XML_DTD_NO_PREFIX)); rb_define_const(eXMLError, "DTD_NO_ROOT", INT2NUM(XML_DTD_NO_ROOT)); rb_define_const(eXMLError, "DTD_NOTATION_REDEFINED", INT2NUM(XML_DTD_NOTATION_REDEFINED)); rb_define_const(eXMLError, "DTD_NOTATION_VALUE", INT2NUM(XML_DTD_NOTATION_VALUE)); rb_define_const(eXMLError, "DTD_NOT_EMPTY", INT2NUM(XML_DTD_NOT_EMPTY)); rb_define_const(eXMLError, "DTD_NOT_PCDATA", INT2NUM(XML_DTD_NOT_PCDATA)); rb_define_const(eXMLError, "DTD_NOT_STANDALONE", INT2NUM(XML_DTD_NOT_STANDALONE)); rb_define_const(eXMLError, "DTD_ROOT_NAME", INT2NUM(XML_DTD_ROOT_NAME)); rb_define_const(eXMLError, "DTD_STANDALONE_WHITE_SPACE", INT2NUM(XML_DTD_STANDALONE_WHITE_SPACE)); rb_define_const(eXMLError, "DTD_UNKNOWN_ATTRIBUTE", INT2NUM(XML_DTD_UNKNOWN_ATTRIBUTE)); rb_define_const(eXMLError, "DTD_UNKNOWN_ELEM", INT2NUM(XML_DTD_UNKNOWN_ELEM)); rb_define_const(eXMLError, "DTD_UNKNOWN_ENTITY", INT2NUM(XML_DTD_UNKNOWN_ENTITY)); rb_define_const(eXMLError, "DTD_UNKNOWN_ID", INT2NUM(XML_DTD_UNKNOWN_ID)); rb_define_const(eXMLError, "DTD_UNKNOWN_NOTATION", INT2NUM(XML_DTD_UNKNOWN_NOTATION)); rb_define_const(eXMLError, "DTD_STANDALONE_DEFAULTED", INT2NUM(XML_DTD_STANDALONE_DEFAULTED)); rb_define_const(eXMLError, "DTD_XMLID_VALUE", INT2NUM(XML_DTD_XMLID_VALUE)); rb_define_const(eXMLError, "DTD_XMLID_TYPE", INT2NUM(XML_DTD_XMLID_TYPE)); rb_define_const(eXMLError, "HTML_STRUCURE_ERROR", INT2NUM(XML_HTML_STRUCURE_ERROR)); rb_define_const(eXMLError, "HTML_UNKNOWN_TAG", INT2NUM(XML_HTML_UNKNOWN_TAG)); rb_define_const(eXMLError, "RNGP_ANYNAME_ATTR_ANCESTOR", INT2NUM(XML_RNGP_ANYNAME_ATTR_ANCESTOR)); rb_define_const(eXMLError, "RNGP_ATTR_CONFLICT", INT2NUM(XML_RNGP_ATTR_CONFLICT)); rb_define_const(eXMLError, "RNGP_ATTRIBUTE_CHILDREN", INT2NUM(XML_RNGP_ATTRIBUTE_CHILDREN)); rb_define_const(eXMLError, "RNGP_ATTRIBUTE_CONTENT", INT2NUM(XML_RNGP_ATTRIBUTE_CONTENT)); rb_define_const(eXMLError, "RNGP_ATTRIBUTE_EMPTY", INT2NUM(XML_RNGP_ATTRIBUTE_EMPTY)); rb_define_const(eXMLError, "RNGP_ATTRIBUTE_NOOP", INT2NUM(XML_RNGP_ATTRIBUTE_NOOP)); rb_define_const(eXMLError, "RNGP_CHOICE_CONTENT", INT2NUM(XML_RNGP_CHOICE_CONTENT)); rb_define_const(eXMLError, "RNGP_CHOICE_EMPTY", INT2NUM(XML_RNGP_CHOICE_EMPTY)); rb_define_const(eXMLError, "RNGP_CREATE_FAILURE", INT2NUM(XML_RNGP_CREATE_FAILURE)); rb_define_const(eXMLError, "RNGP_DATA_CONTENT", INT2NUM(XML_RNGP_DATA_CONTENT)); rb_define_const(eXMLError, "RNGP_DEF_CHOICE_AND_INTERLEAVE", INT2NUM(XML_RNGP_DEF_CHOICE_AND_INTERLEAVE)); rb_define_const(eXMLError, "RNGP_DEFINE_CREATE_FAILED", INT2NUM(XML_RNGP_DEFINE_CREATE_FAILED)); rb_define_const(eXMLError, "RNGP_DEFINE_EMPTY", INT2NUM(XML_RNGP_DEFINE_EMPTY)); rb_define_const(eXMLError, "RNGP_DEFINE_MISSING", INT2NUM(XML_RNGP_DEFINE_MISSING)); rb_define_const(eXMLError, "RNGP_DEFINE_NAME_MISSING", INT2NUM(XML_RNGP_DEFINE_NAME_MISSING)); rb_define_const(eXMLError, "RNGP_ELEM_CONTENT_EMPTY", INT2NUM(XML_RNGP_ELEM_CONTENT_EMPTY)); rb_define_const(eXMLError, "RNGP_ELEM_CONTENT_ERROR", INT2NUM(XML_RNGP_ELEM_CONTENT_ERROR)); rb_define_const(eXMLError, "RNGP_ELEMENT_EMPTY", INT2NUM(XML_RNGP_ELEMENT_EMPTY)); rb_define_const(eXMLError, "RNGP_ELEMENT_CONTENT", INT2NUM(XML_RNGP_ELEMENT_CONTENT)); rb_define_const(eXMLError, "RNGP_ELEMENT_NAME", INT2NUM(XML_RNGP_ELEMENT_NAME)); rb_define_const(eXMLError, "RNGP_ELEMENT_NO_CONTENT", INT2NUM(XML_RNGP_ELEMENT_NO_CONTENT)); rb_define_const(eXMLError, "RNGP_ELEM_TEXT_CONFLICT", INT2NUM(XML_RNGP_ELEM_TEXT_CONFLICT)); rb_define_const(eXMLError, "RNGP_EMPTY", INT2NUM(XML_RNGP_EMPTY)); rb_define_const(eXMLError, "RNGP_EMPTY_CONSTRUCT", INT2NUM(XML_RNGP_EMPTY_CONSTRUCT)); rb_define_const(eXMLError, "RNGP_EMPTY_CONTENT", INT2NUM(XML_RNGP_EMPTY_CONTENT)); rb_define_const(eXMLError, "RNGP_EMPTY_NOT_EMPTY", INT2NUM(XML_RNGP_EMPTY_NOT_EMPTY)); rb_define_const(eXMLError, "RNGP_ERROR_TYPE_LIB", INT2NUM(XML_RNGP_ERROR_TYPE_LIB)); rb_define_const(eXMLError, "RNGP_EXCEPT_EMPTY", INT2NUM(XML_RNGP_EXCEPT_EMPTY)); rb_define_const(eXMLError, "RNGP_EXCEPT_MISSING", INT2NUM(XML_RNGP_EXCEPT_MISSING)); rb_define_const(eXMLError, "RNGP_EXCEPT_MULTIPLE", INT2NUM(XML_RNGP_EXCEPT_MULTIPLE)); rb_define_const(eXMLError, "RNGP_EXCEPT_NO_CONTENT", INT2NUM(XML_RNGP_EXCEPT_NO_CONTENT)); rb_define_const(eXMLError, "RNGP_EXTERNALREF_EMTPY", INT2NUM(XML_RNGP_EXTERNALREF_EMTPY)); rb_define_const(eXMLError, "RNGP_EXTERNAL_REF_FAILURE", INT2NUM(XML_RNGP_EXTERNAL_REF_FAILURE)); rb_define_const(eXMLError, "RNGP_EXTERNALREF_RECURSE", INT2NUM(XML_RNGP_EXTERNALREF_RECURSE)); rb_define_const(eXMLError, "RNGP_FORBIDDEN_ATTRIBUTE", INT2NUM(XML_RNGP_FORBIDDEN_ATTRIBUTE)); rb_define_const(eXMLError, "RNGP_FOREIGN_ELEMENT", INT2NUM(XML_RNGP_FOREIGN_ELEMENT)); rb_define_const(eXMLError, "RNGP_GRAMMAR_CONTENT", INT2NUM(XML_RNGP_GRAMMAR_CONTENT)); rb_define_const(eXMLError, "RNGP_GRAMMAR_EMPTY", INT2NUM(XML_RNGP_GRAMMAR_EMPTY)); rb_define_const(eXMLError, "RNGP_GRAMMAR_MISSING", INT2NUM(XML_RNGP_GRAMMAR_MISSING)); rb_define_const(eXMLError, "RNGP_GRAMMAR_NO_START", INT2NUM(XML_RNGP_GRAMMAR_NO_START)); rb_define_const(eXMLError, "RNGP_GROUP_ATTR_CONFLICT", INT2NUM(XML_RNGP_GROUP_ATTR_CONFLICT)); rb_define_const(eXMLError, "RNGP_HREF_ERROR", INT2NUM(XML_RNGP_HREF_ERROR)); rb_define_const(eXMLError, "RNGP_INCLUDE_EMPTY", INT2NUM(XML_RNGP_INCLUDE_EMPTY)); rb_define_const(eXMLError, "RNGP_INCLUDE_FAILURE", INT2NUM(XML_RNGP_INCLUDE_FAILURE)); rb_define_const(eXMLError, "RNGP_INCLUDE_RECURSE", INT2NUM(XML_RNGP_INCLUDE_RECURSE)); rb_define_const(eXMLError, "RNGP_INTERLEAVE_ADD", INT2NUM(XML_RNGP_INTERLEAVE_ADD)); rb_define_const(eXMLError, "RNGP_INTERLEAVE_CREATE_FAILED", INT2NUM(XML_RNGP_INTERLEAVE_CREATE_FAILED)); rb_define_const(eXMLError, "RNGP_INTERLEAVE_EMPTY", INT2NUM(XML_RNGP_INTERLEAVE_EMPTY)); rb_define_const(eXMLError, "RNGP_INTERLEAVE_NO_CONTENT", INT2NUM(XML_RNGP_INTERLEAVE_NO_CONTENT)); rb_define_const(eXMLError, "RNGP_INVALID_DEFINE_NAME", INT2NUM(XML_RNGP_INVALID_DEFINE_NAME)); rb_define_const(eXMLError, "RNGP_INVALID_URI", INT2NUM(XML_RNGP_INVALID_URI)); rb_define_const(eXMLError, "RNGP_INVALID_VALUE", INT2NUM(XML_RNGP_INVALID_VALUE)); rb_define_const(eXMLError, "RNGP_MISSING_HREF", INT2NUM(XML_RNGP_MISSING_HREF)); rb_define_const(eXMLError, "RNGP_NAME_MISSING", INT2NUM(XML_RNGP_NAME_MISSING)); rb_define_const(eXMLError, "RNGP_NEED_COMBINE", INT2NUM(XML_RNGP_NEED_COMBINE)); rb_define_const(eXMLError, "RNGP_NOTALLOWED_NOT_EMPTY", INT2NUM(XML_RNGP_NOTALLOWED_NOT_EMPTY)); rb_define_const(eXMLError, "RNGP_NSNAME_ATTR_ANCESTOR", INT2NUM(XML_RNGP_NSNAME_ATTR_ANCESTOR)); rb_define_const(eXMLError, "RNGP_NSNAME_NO_NS", INT2NUM(XML_RNGP_NSNAME_NO_NS)); rb_define_const(eXMLError, "RNGP_PARAM_FORBIDDEN", INT2NUM(XML_RNGP_PARAM_FORBIDDEN)); rb_define_const(eXMLError, "RNGP_PARAM_NAME_MISSING", INT2NUM(XML_RNGP_PARAM_NAME_MISSING)); rb_define_const(eXMLError, "RNGP_PARENTREF_CREATE_FAILED", INT2NUM(XML_RNGP_PARENTREF_CREATE_FAILED)); rb_define_const(eXMLError, "RNGP_PARENTREF_NAME_INVALID", INT2NUM(XML_RNGP_PARENTREF_NAME_INVALID)); rb_define_const(eXMLError, "RNGP_PARENTREF_NO_NAME", INT2NUM(XML_RNGP_PARENTREF_NO_NAME)); rb_define_const(eXMLError, "RNGP_PARENTREF_NO_PARENT", INT2NUM(XML_RNGP_PARENTREF_NO_PARENT)); rb_define_const(eXMLError, "RNGP_PARENTREF_NOT_EMPTY", INT2NUM(XML_RNGP_PARENTREF_NOT_EMPTY)); rb_define_const(eXMLError, "RNGP_PARSE_ERROR", INT2NUM(XML_RNGP_PARSE_ERROR)); rb_define_const(eXMLError, "RNGP_PAT_ANYNAME_EXCEPT_ANYNAME", INT2NUM(XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME)); rb_define_const(eXMLError, "RNGP_PAT_ATTR_ATTR", INT2NUM(XML_RNGP_PAT_ATTR_ATTR)); rb_define_const(eXMLError, "RNGP_PAT_ATTR_ELEM", INT2NUM(XML_RNGP_PAT_ATTR_ELEM)); rb_define_const(eXMLError, "RNGP_PAT_DATA_EXCEPT_ATTR", INT2NUM(XML_RNGP_PAT_DATA_EXCEPT_ATTR)); rb_define_const(eXMLError, "RNGP_PAT_DATA_EXCEPT_ELEM", INT2NUM(XML_RNGP_PAT_DATA_EXCEPT_ELEM)); rb_define_const(eXMLError, "RNGP_PAT_DATA_EXCEPT_EMPTY", INT2NUM(XML_RNGP_PAT_DATA_EXCEPT_EMPTY)); rb_define_const(eXMLError, "RNGP_PAT_DATA_EXCEPT_GROUP", INT2NUM(XML_RNGP_PAT_DATA_EXCEPT_GROUP)); rb_define_const(eXMLError, "RNGP_PAT_DATA_EXCEPT_INTERLEAVE", INT2NUM(XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE)); rb_define_const(eXMLError, "RNGP_PAT_DATA_EXCEPT_LIST", INT2NUM(XML_RNGP_PAT_DATA_EXCEPT_LIST)); rb_define_const(eXMLError, "RNGP_PAT_DATA_EXCEPT_ONEMORE", INT2NUM(XML_RNGP_PAT_DATA_EXCEPT_ONEMORE)); rb_define_const(eXMLError, "RNGP_PAT_DATA_EXCEPT_REF", INT2NUM(XML_RNGP_PAT_DATA_EXCEPT_REF)); rb_define_const(eXMLError, "RNGP_PAT_DATA_EXCEPT_TEXT", INT2NUM(XML_RNGP_PAT_DATA_EXCEPT_TEXT)); rb_define_const(eXMLError, "RNGP_PAT_LIST_ATTR", INT2NUM(XML_RNGP_PAT_LIST_ATTR)); rb_define_const(eXMLError, "RNGP_PAT_LIST_ELEM", INT2NUM(XML_RNGP_PAT_LIST_ELEM)); rb_define_const(eXMLError, "RNGP_PAT_LIST_INTERLEAVE", INT2NUM(XML_RNGP_PAT_LIST_INTERLEAVE)); rb_define_const(eXMLError, "RNGP_PAT_LIST_LIST", INT2NUM(XML_RNGP_PAT_LIST_LIST)); rb_define_const(eXMLError, "RNGP_PAT_LIST_REF", INT2NUM(XML_RNGP_PAT_LIST_REF)); rb_define_const(eXMLError, "RNGP_PAT_LIST_TEXT", INT2NUM(XML_RNGP_PAT_LIST_TEXT)); rb_define_const(eXMLError, "RNGP_PAT_NSNAME_EXCEPT_ANYNAME", INT2NUM(XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME)); rb_define_const(eXMLError, "RNGP_PAT_NSNAME_EXCEPT_NSNAME", INT2NUM(XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME)); rb_define_const(eXMLError, "RNGP_PAT_ONEMORE_GROUP_ATTR", INT2NUM(XML_RNGP_PAT_ONEMORE_GROUP_ATTR)); rb_define_const(eXMLError, "RNGP_PAT_ONEMORE_INTERLEAVE_ATTR", INT2NUM(XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR)); rb_define_const(eXMLError, "RNGP_PAT_START_ATTR", INT2NUM(XML_RNGP_PAT_START_ATTR)); rb_define_const(eXMLError, "RNGP_PAT_START_DATA", INT2NUM(XML_RNGP_PAT_START_DATA)); rb_define_const(eXMLError, "RNGP_PAT_START_EMPTY", INT2NUM(XML_RNGP_PAT_START_EMPTY)); rb_define_const(eXMLError, "RNGP_PAT_START_GROUP", INT2NUM(XML_RNGP_PAT_START_GROUP)); rb_define_const(eXMLError, "RNGP_PAT_START_INTERLEAVE", INT2NUM(XML_RNGP_PAT_START_INTERLEAVE)); rb_define_const(eXMLError, "RNGP_PAT_START_LIST", INT2NUM(XML_RNGP_PAT_START_LIST)); rb_define_const(eXMLError, "RNGP_PAT_START_ONEMORE", INT2NUM(XML_RNGP_PAT_START_ONEMORE)); rb_define_const(eXMLError, "RNGP_PAT_START_TEXT", INT2NUM(XML_RNGP_PAT_START_TEXT)); rb_define_const(eXMLError, "RNGP_PAT_START_VALUE", INT2NUM(XML_RNGP_PAT_START_VALUE)); rb_define_const(eXMLError, "RNGP_PREFIX_UNDEFINED", INT2NUM(XML_RNGP_PREFIX_UNDEFINED)); rb_define_const(eXMLError, "RNGP_REF_CREATE_FAILED", INT2NUM(XML_RNGP_REF_CREATE_FAILED)); rb_define_const(eXMLError, "RNGP_REF_CYCLE", INT2NUM(XML_RNGP_REF_CYCLE)); rb_define_const(eXMLError, "RNGP_REF_NAME_INVALID", INT2NUM(XML_RNGP_REF_NAME_INVALID)); rb_define_const(eXMLError, "RNGP_REF_NO_DEF", INT2NUM(XML_RNGP_REF_NO_DEF)); rb_define_const(eXMLError, "RNGP_REF_NO_NAME", INT2NUM(XML_RNGP_REF_NO_NAME)); rb_define_const(eXMLError, "RNGP_REF_NOT_EMPTY", INT2NUM(XML_RNGP_REF_NOT_EMPTY)); rb_define_const(eXMLError, "RNGP_START_CHOICE_AND_INTERLEAVE", INT2NUM(XML_RNGP_START_CHOICE_AND_INTERLEAVE)); rb_define_const(eXMLError, "RNGP_START_CONTENT", INT2NUM(XML_RNGP_START_CONTENT)); rb_define_const(eXMLError, "RNGP_START_EMPTY", INT2NUM(XML_RNGP_START_EMPTY)); rb_define_const(eXMLError, "RNGP_START_MISSING", INT2NUM(XML_RNGP_START_MISSING)); rb_define_const(eXMLError, "RNGP_TEXT_EXPECTED", INT2NUM(XML_RNGP_TEXT_EXPECTED)); rb_define_const(eXMLError, "RNGP_TEXT_HAS_CHILD", INT2NUM(XML_RNGP_TEXT_HAS_CHILD)); rb_define_const(eXMLError, "RNGP_TYPE_MISSING", INT2NUM(XML_RNGP_TYPE_MISSING)); rb_define_const(eXMLError, "RNGP_TYPE_NOT_FOUND", INT2NUM(XML_RNGP_TYPE_NOT_FOUND)); rb_define_const(eXMLError, "RNGP_TYPE_VALUE", INT2NUM(XML_RNGP_TYPE_VALUE)); rb_define_const(eXMLError, "RNGP_UNKNOWN_ATTRIBUTE", INT2NUM(XML_RNGP_UNKNOWN_ATTRIBUTE)); rb_define_const(eXMLError, "RNGP_UNKNOWN_COMBINE", INT2NUM(XML_RNGP_UNKNOWN_COMBINE)); rb_define_const(eXMLError, "RNGP_UNKNOWN_CONSTRUCT", INT2NUM(XML_RNGP_UNKNOWN_CONSTRUCT)); rb_define_const(eXMLError, "RNGP_UNKNOWN_TYPE_LIB", INT2NUM(XML_RNGP_UNKNOWN_TYPE_LIB)); rb_define_const(eXMLError, "RNGP_URI_FRAGMENT", INT2NUM(XML_RNGP_URI_FRAGMENT)); rb_define_const(eXMLError, "RNGP_URI_NOT_ABSOLUTE", INT2NUM(XML_RNGP_URI_NOT_ABSOLUTE)); rb_define_const(eXMLError, "RNGP_VALUE_EMPTY", INT2NUM(XML_RNGP_VALUE_EMPTY)); rb_define_const(eXMLError, "RNGP_VALUE_NO_CONTENT", INT2NUM(XML_RNGP_VALUE_NO_CONTENT)); rb_define_const(eXMLError, "RNGP_XMLNS_NAME", INT2NUM(XML_RNGP_XMLNS_NAME)); rb_define_const(eXMLError, "RNGP_XML_NS", INT2NUM(XML_RNGP_XML_NS)); rb_define_const(eXMLError, "XPATH_EXPRESSION_OK", INT2NUM(XML_XPATH_EXPRESSION_OK)); rb_define_const(eXMLError, "XPATH_NUMBER_ERROR", INT2NUM(XML_XPATH_NUMBER_ERROR)); rb_define_const(eXMLError, "XPATH_UNFINISHED_LITERAL_ERROR", INT2NUM(XML_XPATH_UNFINISHED_LITERAL_ERROR)); rb_define_const(eXMLError, "XPATH_START_LITERAL_ERROR", INT2NUM(XML_XPATH_START_LITERAL_ERROR)); rb_define_const(eXMLError, "XPATH_VARIABLE_REF_ERROR", INT2NUM(XML_XPATH_VARIABLE_REF_ERROR)); rb_define_const(eXMLError, "XPATH_UNDEF_VARIABLE_ERROR", INT2NUM(XML_XPATH_UNDEF_VARIABLE_ERROR)); rb_define_const(eXMLError, "XPATH_INVALID_PREDICATE_ERROR", INT2NUM(XML_XPATH_INVALID_PREDICATE_ERROR)); rb_define_const(eXMLError, "XPATH_EXPR_ERROR", INT2NUM(XML_XPATH_EXPR_ERROR)); rb_define_const(eXMLError, "XPATH_UNCLOSED_ERROR", INT2NUM(XML_XPATH_UNCLOSED_ERROR)); rb_define_const(eXMLError, "XPATH_UNKNOWN_FUNC_ERROR", INT2NUM(XML_XPATH_UNKNOWN_FUNC_ERROR)); rb_define_const(eXMLError, "XPATH_INVALID_OPERAND", INT2NUM(XML_XPATH_INVALID_OPERAND)); rb_define_const(eXMLError, "XPATH_INVALID_TYPE", INT2NUM(XML_XPATH_INVALID_TYPE)); rb_define_const(eXMLError, "XPATH_INVALID_ARITY", INT2NUM(XML_XPATH_INVALID_ARITY)); rb_define_const(eXMLError, "XPATH_INVALID_CTXT_SIZE", INT2NUM(XML_XPATH_INVALID_CTXT_SIZE)); rb_define_const(eXMLError, "XPATH_INVALID_CTXT_POSITION", INT2NUM(XML_XPATH_INVALID_CTXT_POSITION)); rb_define_const(eXMLError, "XPATH_MEMORY_ERROR", INT2NUM(XML_XPATH_MEMORY_ERROR)); rb_define_const(eXMLError, "XPTR_SYNTAX_ERROR", INT2NUM(XML_XPTR_SYNTAX_ERROR)); rb_define_const(eXMLError, "XPTR_RESOURCE_ERROR", INT2NUM(XML_XPTR_RESOURCE_ERROR)); rb_define_const(eXMLError, "XPTR_SUB_RESOURCE_ERROR", INT2NUM(XML_XPTR_SUB_RESOURCE_ERROR)); rb_define_const(eXMLError, "XPATH_UNDEF_PREFIX_ERROR", INT2NUM(XML_XPATH_UNDEF_PREFIX_ERROR)); rb_define_const(eXMLError, "XPATH_ENCODING_ERROR", INT2NUM(XML_XPATH_ENCODING_ERROR)); rb_define_const(eXMLError, "XPATH_INVALID_CHAR_ERROR", INT2NUM(XML_XPATH_INVALID_CHAR_ERROR)); rb_define_const(eXMLError, "TREE_INVALID_HEX", INT2NUM(XML_TREE_INVALID_HEX)); rb_define_const(eXMLError, "TREE_INVALID_DEC", INT2NUM(XML_TREE_INVALID_DEC)); rb_define_const(eXMLError, "TREE_UNTERMINATED_ENTITY", INT2NUM(XML_TREE_UNTERMINATED_ENTITY)); #if LIBXML_VERSION >= 20632 rb_define_const(eXMLError, "TREE_NOT_UTF8", INT2NUM(XML_TREE_NOT_UTF8)); #endif rb_define_const(eXMLError, "SAVE_NOT_UTF8", INT2NUM(XML_SAVE_NOT_UTF8)); rb_define_const(eXMLError, "SAVE_CHAR_INVALID", INT2NUM(XML_SAVE_CHAR_INVALID)); rb_define_const(eXMLError, "SAVE_NO_DOCTYPE", INT2NUM(XML_SAVE_NO_DOCTYPE)); rb_define_const(eXMLError, "SAVE_UNKNOWN_ENCODING", INT2NUM(XML_SAVE_UNKNOWN_ENCODING)); rb_define_const(eXMLError, "REGEXP_COMPILE_ERROR", INT2NUM(XML_REGEXP_COMPILE_ERROR)); rb_define_const(eXMLError, "IO_UNKNOWN", INT2NUM(XML_IO_UNKNOWN)); rb_define_const(eXMLError, "IO_EACCES", INT2NUM(XML_IO_EACCES)); rb_define_const(eXMLError, "IO_EAGAIN", INT2NUM(XML_IO_EAGAIN)); rb_define_const(eXMLError, "IO_EBADF", INT2NUM(XML_IO_EBADF)); rb_define_const(eXMLError, "IO_EBADMSG", INT2NUM(XML_IO_EBADMSG)); rb_define_const(eXMLError, "IO_EBUSY", INT2NUM(XML_IO_EBUSY)); rb_define_const(eXMLError, "IO_ECANCELED", INT2NUM(XML_IO_ECANCELED)); rb_define_const(eXMLError, "IO_ECHILD", INT2NUM(XML_IO_ECHILD)); rb_define_const(eXMLError, "IO_EDEADLK", INT2NUM(XML_IO_EDEADLK)); rb_define_const(eXMLError, "IO_EDOM", INT2NUM(XML_IO_EDOM)); rb_define_const(eXMLError, "IO_EEXIST", INT2NUM(XML_IO_EEXIST)); rb_define_const(eXMLError, "IO_EFAULT", INT2NUM(XML_IO_EFAULT)); rb_define_const(eXMLError, "IO_EFBIG", INT2NUM(XML_IO_EFBIG)); rb_define_const(eXMLError, "IO_EINPROGRESS", INT2NUM(XML_IO_EINPROGRESS)); rb_define_const(eXMLError, "IO_EINTR", INT2NUM(XML_IO_EINTR)); rb_define_const(eXMLError, "IO_EINVAL", INT2NUM(XML_IO_EINVAL)); rb_define_const(eXMLError, "IO_EIO", INT2NUM(XML_IO_EIO)); rb_define_const(eXMLError, "IO_EISDIR", INT2NUM(XML_IO_EISDIR)); rb_define_const(eXMLError, "IO_EMFILE", INT2NUM(XML_IO_EMFILE)); rb_define_const(eXMLError, "IO_EMLINK", INT2NUM(XML_IO_EMLINK)); rb_define_const(eXMLError, "IO_EMSGSIZE", INT2NUM(XML_IO_EMSGSIZE)); rb_define_const(eXMLError, "IO_ENAMETOOLONG", INT2NUM(XML_IO_ENAMETOOLONG)); rb_define_const(eXMLError, "IO_ENFILE", INT2NUM(XML_IO_ENFILE)); rb_define_const(eXMLError, "IO_ENODEV", INT2NUM(XML_IO_ENODEV)); rb_define_const(eXMLError, "IO_ENOENT", INT2NUM(XML_IO_ENOENT)); rb_define_const(eXMLError, "IO_ENOEXEC", INT2NUM(XML_IO_ENOEXEC)); rb_define_const(eXMLError, "IO_ENOLCK", INT2NUM(XML_IO_ENOLCK)); rb_define_const(eXMLError, "IO_ENOMEM", INT2NUM(XML_IO_ENOMEM)); rb_define_const(eXMLError, "IO_ENOSPC", INT2NUM(XML_IO_ENOSPC)); rb_define_const(eXMLError, "IO_ENOSYS", INT2NUM(XML_IO_ENOSYS)); rb_define_const(eXMLError, "IO_ENOTDIR", INT2NUM(XML_IO_ENOTDIR)); rb_define_const(eXMLError, "IO_ENOTEMPTY", INT2NUM(XML_IO_ENOTEMPTY)); rb_define_const(eXMLError, "IO_ENOTSUP", INT2NUM(XML_IO_ENOTSUP)); rb_define_const(eXMLError, "IO_ENOTTY", INT2NUM(XML_IO_ENOTTY)); rb_define_const(eXMLError, "IO_ENXIO", INT2NUM(XML_IO_ENXIO)); rb_define_const(eXMLError, "IO_EPERM", INT2NUM(XML_IO_EPERM)); rb_define_const(eXMLError, "IO_EPIPE", INT2NUM(XML_IO_EPIPE)); rb_define_const(eXMLError, "IO_ERANGE", INT2NUM(XML_IO_ERANGE)); rb_define_const(eXMLError, "IO_EROFS", INT2NUM(XML_IO_EROFS)); rb_define_const(eXMLError, "IO_ESPIPE", INT2NUM(XML_IO_ESPIPE)); rb_define_const(eXMLError, "IO_ESRCH", INT2NUM(XML_IO_ESRCH)); rb_define_const(eXMLError, "IO_ETIMEDOUT", INT2NUM(XML_IO_ETIMEDOUT)); rb_define_const(eXMLError, "IO_EXDEV", INT2NUM(XML_IO_EXDEV)); rb_define_const(eXMLError, "IO_NETWORK_ATTEMPT", INT2NUM(XML_IO_NETWORK_ATTEMPT)); rb_define_const(eXMLError, "IO_ENCODER", INT2NUM(XML_IO_ENCODER)); rb_define_const(eXMLError, "IO_FLUSH", INT2NUM(XML_IO_FLUSH)); rb_define_const(eXMLError, "IO_WRITE", INT2NUM(XML_IO_WRITE)); rb_define_const(eXMLError, "IO_NO_INPUT", INT2NUM(XML_IO_NO_INPUT)); rb_define_const(eXMLError, "IO_BUFFER_FULL", INT2NUM(XML_IO_BUFFER_FULL)); rb_define_const(eXMLError, "IO_LOAD_ERROR", INT2NUM(XML_IO_LOAD_ERROR)); rb_define_const(eXMLError, "IO_ENOTSOCK", INT2NUM(XML_IO_ENOTSOCK)); rb_define_const(eXMLError, "IO_EISCONN", INT2NUM(XML_IO_EISCONN)); rb_define_const(eXMLError, "IO_ECONNREFUSED", INT2NUM(XML_IO_ECONNREFUSED)); rb_define_const(eXMLError, "IO_ENETUNREACH", INT2NUM(XML_IO_ENETUNREACH)); rb_define_const(eXMLError, "IO_EADDRINUSE", INT2NUM(XML_IO_EADDRINUSE)); rb_define_const(eXMLError, "IO_EALREADY", INT2NUM(XML_IO_EALREADY)); rb_define_const(eXMLError, "IO_EAFNOSUPPORT", INT2NUM(XML_IO_EAFNOSUPPORT)); rb_define_const(eXMLError, "XINCLUDE_RECURSION", INT2NUM(XML_XINCLUDE_RECURSION)); rb_define_const(eXMLError, "XINCLUDE_PARSE_VALUE", INT2NUM(XML_XINCLUDE_PARSE_VALUE)); rb_define_const(eXMLError, "XINCLUDE_ENTITY_DEF_MISMATCH", INT2NUM(XML_XINCLUDE_ENTITY_DEF_MISMATCH)); rb_define_const(eXMLError, "XINCLUDE_NO_HREF", INT2NUM(XML_XINCLUDE_NO_HREF)); rb_define_const(eXMLError, "XINCLUDE_NO_FALLBACK", INT2NUM(XML_XINCLUDE_NO_FALLBACK)); rb_define_const(eXMLError, "XINCLUDE_HREF_URI", INT2NUM(XML_XINCLUDE_HREF_URI)); rb_define_const(eXMLError, "XINCLUDE_TEXT_FRAGMENT", INT2NUM(XML_XINCLUDE_TEXT_FRAGMENT)); rb_define_const(eXMLError, "XINCLUDE_TEXT_DOCUMENT", INT2NUM(XML_XINCLUDE_TEXT_DOCUMENT)); rb_define_const(eXMLError, "XINCLUDE_INVALID_CHAR", INT2NUM(XML_XINCLUDE_INVALID_CHAR)); rb_define_const(eXMLError, "XINCLUDE_BUILD_FAILED", INT2NUM(XML_XINCLUDE_BUILD_FAILED)); rb_define_const(eXMLError, "XINCLUDE_UNKNOWN_ENCODING", INT2NUM(XML_XINCLUDE_UNKNOWN_ENCODING)); rb_define_const(eXMLError, "XINCLUDE_MULTIPLE_ROOT", INT2NUM(XML_XINCLUDE_MULTIPLE_ROOT)); rb_define_const(eXMLError, "XINCLUDE_XPTR_FAILED", INT2NUM(XML_XINCLUDE_XPTR_FAILED)); rb_define_const(eXMLError, "XINCLUDE_XPTR_RESULT", INT2NUM(XML_XINCLUDE_XPTR_RESULT)); rb_define_const(eXMLError, "XINCLUDE_INCLUDE_IN_INCLUDE", INT2NUM(XML_XINCLUDE_INCLUDE_IN_INCLUDE)); rb_define_const(eXMLError, "XINCLUDE_FALLBACKS_IN_INCLUDE", INT2NUM(XML_XINCLUDE_FALLBACKS_IN_INCLUDE)); rb_define_const(eXMLError, "XINCLUDE_FALLBACK_NOT_IN_INCLUDE", INT2NUM(XML_XINCLUDE_FALLBACK_NOT_IN_INCLUDE)); rb_define_const(eXMLError, "XINCLUDE_DEPRECATED_NS", INT2NUM(XML_XINCLUDE_DEPRECATED_NS)); rb_define_const(eXMLError, "XINCLUDE_FRAGMENT_ID", INT2NUM(XML_XINCLUDE_FRAGMENT_ID)); rb_define_const(eXMLError, "CATALOG_MISSING_ATTR", INT2NUM(XML_CATALOG_MISSING_ATTR)); rb_define_const(eXMLError, "CATALOG_ENTRY_BROKEN", INT2NUM(XML_CATALOG_ENTRY_BROKEN)); rb_define_const(eXMLError, "CATALOG_PREFER_VALUE", INT2NUM(XML_CATALOG_PREFER_VALUE)); rb_define_const(eXMLError, "CATALOG_NOT_CATALOG", INT2NUM(XML_CATALOG_NOT_CATALOG)); rb_define_const(eXMLError, "CATALOG_RECURSION", INT2NUM(XML_CATALOG_RECURSION)); rb_define_const(eXMLError, "SCHEMAP_PREFIX_UNDEFINED", INT2NUM(XML_SCHEMAP_PREFIX_UNDEFINED)); rb_define_const(eXMLError, "SCHEMAP_ATTRFORMDEFAULT_VALUE", INT2NUM(XML_SCHEMAP_ATTRFORMDEFAULT_VALUE)); rb_define_const(eXMLError, "SCHEMAP_ATTRGRP_NONAME_NOREF", INT2NUM(XML_SCHEMAP_ATTRGRP_NONAME_NOREF)); rb_define_const(eXMLError, "SCHEMAP_ATTR_NONAME_NOREF", INT2NUM(XML_SCHEMAP_ATTR_NONAME_NOREF)); rb_define_const(eXMLError, "SCHEMAP_COMPLEXTYPE_NONAME_NOREF", INT2NUM(XML_SCHEMAP_COMPLEXTYPE_NONAME_NOREF)); rb_define_const(eXMLError, "SCHEMAP_ELEMFORMDEFAULT_VALUE", INT2NUM(XML_SCHEMAP_ELEMFORMDEFAULT_VALUE)); rb_define_const(eXMLError, "SCHEMAP_ELEM_NONAME_NOREF", INT2NUM(XML_SCHEMAP_ELEM_NONAME_NOREF)); rb_define_const(eXMLError, "SCHEMAP_EXTENSION_NO_BASE", INT2NUM(XML_SCHEMAP_EXTENSION_NO_BASE)); rb_define_const(eXMLError, "SCHEMAP_FACET_NO_VALUE", INT2NUM(XML_SCHEMAP_FACET_NO_VALUE)); rb_define_const(eXMLError, "SCHEMAP_FAILED_BUILD_IMPORT", INT2NUM(XML_SCHEMAP_FAILED_BUILD_IMPORT)); rb_define_const(eXMLError, "SCHEMAP_GROUP_NONAME_NOREF", INT2NUM(XML_SCHEMAP_GROUP_NONAME_NOREF)); rb_define_const(eXMLError, "SCHEMAP_IMPORT_NAMESPACE_NOT_URI", INT2NUM(XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI)); rb_define_const(eXMLError, "SCHEMAP_IMPORT_REDEFINE_NSNAME", INT2NUM(XML_SCHEMAP_IMPORT_REDEFINE_NSNAME)); rb_define_const(eXMLError, "SCHEMAP_IMPORT_SCHEMA_NOT_URI", INT2NUM(XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI)); rb_define_const(eXMLError, "SCHEMAP_INVALID_BOOLEAN", INT2NUM(XML_SCHEMAP_INVALID_BOOLEAN)); rb_define_const(eXMLError, "SCHEMAP_INVALID_ENUM", INT2NUM(XML_SCHEMAP_INVALID_ENUM)); rb_define_const(eXMLError, "SCHEMAP_INVALID_FACET", INT2NUM(XML_SCHEMAP_INVALID_FACET)); rb_define_const(eXMLError, "SCHEMAP_INVALID_FACET_VALUE", INT2NUM(XML_SCHEMAP_INVALID_FACET_VALUE)); rb_define_const(eXMLError, "SCHEMAP_INVALID_MAXOCCURS", INT2NUM(XML_SCHEMAP_INVALID_MAXOCCURS)); rb_define_const(eXMLError, "SCHEMAP_INVALID_MINOCCURS", INT2NUM(XML_SCHEMAP_INVALID_MINOCCURS)); rb_define_const(eXMLError, "SCHEMAP_INVALID_REF_AND_SUBTYPE", INT2NUM(XML_SCHEMAP_INVALID_REF_AND_SUBTYPE)); rb_define_const(eXMLError, "SCHEMAP_INVALID_WHITE_SPACE", INT2NUM(XML_SCHEMAP_INVALID_WHITE_SPACE)); rb_define_const(eXMLError, "SCHEMAP_NOATTR_NOREF", INT2NUM(XML_SCHEMAP_NOATTR_NOREF)); rb_define_const(eXMLError, "SCHEMAP_NOTATION_NO_NAME", INT2NUM(XML_SCHEMAP_NOTATION_NO_NAME)); rb_define_const(eXMLError, "SCHEMAP_NOTYPE_NOREF", INT2NUM(XML_SCHEMAP_NOTYPE_NOREF)); rb_define_const(eXMLError, "SCHEMAP_REF_AND_SUBTYPE", INT2NUM(XML_SCHEMAP_REF_AND_SUBTYPE)); rb_define_const(eXMLError, "SCHEMAP_RESTRICTION_NONAME_NOREF", INT2NUM(XML_SCHEMAP_RESTRICTION_NONAME_NOREF)); rb_define_const(eXMLError, "SCHEMAP_SIMPLETYPE_NONAME", INT2NUM(XML_SCHEMAP_SIMPLETYPE_NONAME)); rb_define_const(eXMLError, "SCHEMAP_TYPE_AND_SUBTYPE", INT2NUM(XML_SCHEMAP_TYPE_AND_SUBTYPE)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_ALL_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_ALL_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_ATTR_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_ATTR_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_ATTRGRP_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP", INT2NUM(XML_SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_BASE_TYPE", INT2NUM(XML_SCHEMAP_UNKNOWN_BASE_TYPE)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_CHOICE_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_CHOICE_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_ELEM_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_ELEM_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_EXTENSION_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_FACET_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_FACET_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_FACET_TYPE", INT2NUM(XML_SCHEMAP_UNKNOWN_FACET_TYPE)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_GROUP_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_GROUP_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_IMPORT_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_IMPORT_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_LIST_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_LIST_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_NOTATION_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_NOTATION_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_REF", INT2NUM(XML_SCHEMAP_UNKNOWN_REF)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_RESTRICTION_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_SCHEMAS_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_SEQUENCE_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_TYPE", INT2NUM(XML_SCHEMAP_UNKNOWN_TYPE)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_UNION_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_UNION_CHILD)); rb_define_const(eXMLError, "SCHEMAP_ELEM_DEFAULT_FIXED", INT2NUM(XML_SCHEMAP_ELEM_DEFAULT_FIXED)); rb_define_const(eXMLError, "SCHEMAP_REGEXP_INVALID", INT2NUM(XML_SCHEMAP_REGEXP_INVALID)); rb_define_const(eXMLError, "SCHEMAP_FAILED_LOAD", INT2NUM(XML_SCHEMAP_FAILED_LOAD)); rb_define_const(eXMLError, "SCHEMAP_NOTHING_TO_PARSE", INT2NUM(XML_SCHEMAP_NOTHING_TO_PARSE)); rb_define_const(eXMLError, "SCHEMAP_NOROOT", INT2NUM(XML_SCHEMAP_NOROOT)); rb_define_const(eXMLError, "SCHEMAP_REDEFINED_GROUP", INT2NUM(XML_SCHEMAP_REDEFINED_GROUP)); rb_define_const(eXMLError, "SCHEMAP_REDEFINED_TYPE", INT2NUM(XML_SCHEMAP_REDEFINED_TYPE)); rb_define_const(eXMLError, "SCHEMAP_REDEFINED_ELEMENT", INT2NUM(XML_SCHEMAP_REDEFINED_ELEMENT)); rb_define_const(eXMLError, "SCHEMAP_REDEFINED_ATTRGROUP", INT2NUM(XML_SCHEMAP_REDEFINED_ATTRGROUP)); rb_define_const(eXMLError, "SCHEMAP_REDEFINED_ATTR", INT2NUM(XML_SCHEMAP_REDEFINED_ATTR)); rb_define_const(eXMLError, "SCHEMAP_REDEFINED_NOTATION", INT2NUM(XML_SCHEMAP_REDEFINED_NOTATION)); rb_define_const(eXMLError, "SCHEMAP_FAILED_PARSE", INT2NUM(XML_SCHEMAP_FAILED_PARSE)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_PREFIX", INT2NUM(XML_SCHEMAP_UNKNOWN_PREFIX)); rb_define_const(eXMLError, "SCHEMAP_DEF_AND_PREFIX", INT2NUM(XML_SCHEMAP_DEF_AND_PREFIX)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_INCLUDE_CHILD", INT2NUM(XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD)); rb_define_const(eXMLError, "SCHEMAP_INCLUDE_SCHEMA_NOT_URI", INT2NUM(XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI)); rb_define_const(eXMLError, "SCHEMAP_INCLUDE_SCHEMA_NO_URI", INT2NUM(XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI)); rb_define_const(eXMLError, "SCHEMAP_NOT_SCHEMA", INT2NUM(XML_SCHEMAP_NOT_SCHEMA)); rb_define_const(eXMLError, "SCHEMAP_UNKNOWN_MEMBER_TYPE", INT2NUM(XML_SCHEMAP_UNKNOWN_MEMBER_TYPE)); rb_define_const(eXMLError, "SCHEMAP_INVALID_ATTR_USE", INT2NUM(XML_SCHEMAP_INVALID_ATTR_USE)); rb_define_const(eXMLError, "SCHEMAP_RECURSIVE", INT2NUM(XML_SCHEMAP_RECURSIVE)); rb_define_const(eXMLError, "SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE", INT2NUM(XML_SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE)); rb_define_const(eXMLError, "SCHEMAP_INVALID_ATTR_COMBINATION", INT2NUM(XML_SCHEMAP_INVALID_ATTR_COMBINATION)); rb_define_const(eXMLError, "SCHEMAP_INVALID_ATTR_INLINE_COMBINATION", INT2NUM(XML_SCHEMAP_INVALID_ATTR_INLINE_COMBINATION)); rb_define_const(eXMLError, "SCHEMAP_MISSING_SIMPLETYPE_CHILD", INT2NUM(XML_SCHEMAP_MISSING_SIMPLETYPE_CHILD)); rb_define_const(eXMLError, "SCHEMAP_INVALID_ATTR_NAME", INT2NUM(XML_SCHEMAP_INVALID_ATTR_NAME)); rb_define_const(eXMLError, "SCHEMAP_REF_AND_CONTENT", INT2NUM(XML_SCHEMAP_REF_AND_CONTENT)); rb_define_const(eXMLError, "SCHEMAP_CT_PROPS_CORRECT_1", INT2NUM(XML_SCHEMAP_CT_PROPS_CORRECT_1)); rb_define_const(eXMLError, "SCHEMAP_CT_PROPS_CORRECT_2", INT2NUM(XML_SCHEMAP_CT_PROPS_CORRECT_2)); rb_define_const(eXMLError, "SCHEMAP_CT_PROPS_CORRECT_3", INT2NUM(XML_SCHEMAP_CT_PROPS_CORRECT_3)); rb_define_const(eXMLError, "SCHEMAP_CT_PROPS_CORRECT_4", INT2NUM(XML_SCHEMAP_CT_PROPS_CORRECT_4)); rb_define_const(eXMLError, "SCHEMAP_CT_PROPS_CORRECT_5", INT2NUM(XML_SCHEMAP_CT_PROPS_CORRECT_5)); rb_define_const(eXMLError, "SCHEMAP_DERIVATION_OK_RESTRICTION_1", INT2NUM(XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1)); rb_define_const(eXMLError, "SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1", INT2NUM(XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1)); rb_define_const(eXMLError, "SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2", INT2NUM(XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2)); rb_define_const(eXMLError, "SCHEMAP_DERIVATION_OK_RESTRICTION_2_2", INT2NUM(XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2)); rb_define_const(eXMLError, "SCHEMAP_DERIVATION_OK_RESTRICTION_3", INT2NUM(XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3)); rb_define_const(eXMLError, "SCHEMAP_WILDCARD_INVALID_NS_MEMBER", INT2NUM(XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER)); rb_define_const(eXMLError, "SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE", INT2NUM(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE)); rb_define_const(eXMLError, "SCHEMAP_UNION_NOT_EXPRESSIBLE", INT2NUM(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE)); rb_define_const(eXMLError, "SCHEMAP_SRC_IMPORT_3_1", INT2NUM(XML_SCHEMAP_SRC_IMPORT_3_1)); rb_define_const(eXMLError, "SCHEMAP_SRC_IMPORT_3_2", INT2NUM(XML_SCHEMAP_SRC_IMPORT_3_2)); rb_define_const(eXMLError, "SCHEMAP_DERIVATION_OK_RESTRICTION_4_1", INT2NUM(XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1)); rb_define_const(eXMLError, "SCHEMAP_DERIVATION_OK_RESTRICTION_4_2", INT2NUM(XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2)); rb_define_const(eXMLError, "SCHEMAP_DERIVATION_OK_RESTRICTION_4_3", INT2NUM(XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3)); rb_define_const(eXMLError, "SCHEMAP_COS_CT_EXTENDS_1_3", INT2NUM(XML_SCHEMAP_COS_CT_EXTENDS_1_3)); rb_define_const(eXMLError, "SCHEMAV_NOROOT", INT2NUM(XML_SCHEMAV_NOROOT)); rb_define_const(eXMLError, "SCHEMAV_UNDECLAREDELEM", INT2NUM(XML_SCHEMAV_UNDECLAREDELEM)); rb_define_const(eXMLError, "SCHEMAV_NOTTOPLEVEL", INT2NUM(XML_SCHEMAV_NOTTOPLEVEL)); rb_define_const(eXMLError, "SCHEMAV_MISSING", INT2NUM(XML_SCHEMAV_MISSING)); rb_define_const(eXMLError, "SCHEMAV_WRONGELEM", INT2NUM(XML_SCHEMAV_WRONGELEM)); rb_define_const(eXMLError, "SCHEMAV_NOTYPE", INT2NUM(XML_SCHEMAV_NOTYPE)); rb_define_const(eXMLError, "SCHEMAV_NOROLLBACK", INT2NUM(XML_SCHEMAV_NOROLLBACK)); rb_define_const(eXMLError, "SCHEMAV_ISABSTRACT", INT2NUM(XML_SCHEMAV_ISABSTRACT)); rb_define_const(eXMLError, "SCHEMAV_NOTEMPTY", INT2NUM(XML_SCHEMAV_NOTEMPTY)); rb_define_const(eXMLError, "SCHEMAV_ELEMCONT", INT2NUM(XML_SCHEMAV_ELEMCONT)); rb_define_const(eXMLError, "SCHEMAV_HAVEDEFAULT", INT2NUM(XML_SCHEMAV_HAVEDEFAULT)); rb_define_const(eXMLError, "SCHEMAV_NOTNILLABLE", INT2NUM(XML_SCHEMAV_NOTNILLABLE)); rb_define_const(eXMLError, "SCHEMAV_EXTRACONTENT", INT2NUM(XML_SCHEMAV_EXTRACONTENT)); rb_define_const(eXMLError, "SCHEMAV_INVALIDATTR", INT2NUM(XML_SCHEMAV_INVALIDATTR)); rb_define_const(eXMLError, "SCHEMAV_INVALIDELEM", INT2NUM(XML_SCHEMAV_INVALIDELEM)); rb_define_const(eXMLError, "SCHEMAV_NOTDETERMINIST", INT2NUM(XML_SCHEMAV_NOTDETERMINIST)); rb_define_const(eXMLError, "SCHEMAV_CONSTRUCT", INT2NUM(XML_SCHEMAV_CONSTRUCT)); rb_define_const(eXMLError, "SCHEMAV_INTERNAL", INT2NUM(XML_SCHEMAV_INTERNAL)); rb_define_const(eXMLError, "SCHEMAV_NOTSIMPLE", INT2NUM(XML_SCHEMAV_NOTSIMPLE)); rb_define_const(eXMLError, "SCHEMAV_ATTRUNKNOWN", INT2NUM(XML_SCHEMAV_ATTRUNKNOWN)); rb_define_const(eXMLError, "SCHEMAV_ATTRINVALID", INT2NUM(XML_SCHEMAV_ATTRINVALID)); rb_define_const(eXMLError, "SCHEMAV_VALUE", INT2NUM(XML_SCHEMAV_VALUE)); rb_define_const(eXMLError, "SCHEMAV_FACET", INT2NUM(XML_SCHEMAV_FACET)); rb_define_const(eXMLError, "SCHEMAV_CVC_DATATYPE_VALID_1_2_1", INT2NUM(XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_DATATYPE_VALID_1_2_2", INT2NUM(XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2)); rb_define_const(eXMLError, "SCHEMAV_CVC_DATATYPE_VALID_1_2_3", INT2NUM(XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3)); rb_define_const(eXMLError, "SCHEMAV_CVC_TYPE_3_1_1", INT2NUM(XML_SCHEMAV_CVC_TYPE_3_1_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_TYPE_3_1_2", INT2NUM(XML_SCHEMAV_CVC_TYPE_3_1_2)); rb_define_const(eXMLError, "SCHEMAV_CVC_FACET_VALID", INT2NUM(XML_SCHEMAV_CVC_FACET_VALID)); rb_define_const(eXMLError, "SCHEMAV_CVC_LENGTH_VALID", INT2NUM(XML_SCHEMAV_CVC_LENGTH_VALID)); rb_define_const(eXMLError, "SCHEMAV_CVC_MINLENGTH_VALID", INT2NUM(XML_SCHEMAV_CVC_MINLENGTH_VALID)); rb_define_const(eXMLError, "SCHEMAV_CVC_MAXLENGTH_VALID", INT2NUM(XML_SCHEMAV_CVC_MAXLENGTH_VALID)); rb_define_const(eXMLError, "SCHEMAV_CVC_MININCLUSIVE_VALID", INT2NUM(XML_SCHEMAV_CVC_MININCLUSIVE_VALID)); rb_define_const(eXMLError, "SCHEMAV_CVC_MAXINCLUSIVE_VALID", INT2NUM(XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID)); rb_define_const(eXMLError, "SCHEMAV_CVC_MINEXCLUSIVE_VALID", INT2NUM(XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID)); rb_define_const(eXMLError, "SCHEMAV_CVC_MAXEXCLUSIVE_VALID", INT2NUM(XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID)); rb_define_const(eXMLError, "SCHEMAV_CVC_TOTALDIGITS_VALID", INT2NUM(XML_SCHEMAV_CVC_TOTALDIGITS_VALID)); rb_define_const(eXMLError, "SCHEMAV_CVC_FRACTIONDIGITS_VALID", INT2NUM(XML_SCHEMAV_CVC_FRACTIONDIGITS_VALID)); rb_define_const(eXMLError, "SCHEMAV_CVC_PATTERN_VALID", INT2NUM(XML_SCHEMAV_CVC_PATTERN_VALID)); rb_define_const(eXMLError, "SCHEMAV_CVC_ENUMERATION_VALID", INT2NUM(XML_SCHEMAV_CVC_ENUMERATION_VALID)); rb_define_const(eXMLError, "SCHEMAV_CVC_COMPLEX_TYPE_2_1", INT2NUM(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_COMPLEX_TYPE_2_2", INT2NUM(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2)); rb_define_const(eXMLError, "SCHEMAV_CVC_COMPLEX_TYPE_2_3", INT2NUM(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3)); rb_define_const(eXMLError, "SCHEMAV_CVC_COMPLEX_TYPE_2_4", INT2NUM(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_4)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_1", INT2NUM(XML_SCHEMAV_CVC_ELT_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_2", INT2NUM(XML_SCHEMAV_CVC_ELT_2)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_3_1", INT2NUM(XML_SCHEMAV_CVC_ELT_3_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_3_2_1", INT2NUM(XML_SCHEMAV_CVC_ELT_3_2_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_3_2_2", INT2NUM(XML_SCHEMAV_CVC_ELT_3_2_2)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_4_1", INT2NUM(XML_SCHEMAV_CVC_ELT_4_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_4_2", INT2NUM(XML_SCHEMAV_CVC_ELT_4_2)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_4_3", INT2NUM(XML_SCHEMAV_CVC_ELT_4_3)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_5_1_1", INT2NUM(XML_SCHEMAV_CVC_ELT_5_1_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_5_1_2", INT2NUM(XML_SCHEMAV_CVC_ELT_5_1_2)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_5_2_1", INT2NUM(XML_SCHEMAV_CVC_ELT_5_2_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_5_2_2_1", INT2NUM(XML_SCHEMAV_CVC_ELT_5_2_2_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_5_2_2_2_1", INT2NUM(XML_SCHEMAV_CVC_ELT_5_2_2_2_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_5_2_2_2_2", INT2NUM(XML_SCHEMAV_CVC_ELT_5_2_2_2_2)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_6", INT2NUM(XML_SCHEMAV_CVC_ELT_6)); rb_define_const(eXMLError, "SCHEMAV_CVC_ELT_7",INT2NUM(XML_SCHEMAV_CVC_ELT_7)); rb_define_const(eXMLError, "SCHEMAV_CVC_ATTRIBUTE_1", INT2NUM(XML_SCHEMAV_CVC_ATTRIBUTE_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_ATTRIBUTE_2", INT2NUM(XML_SCHEMAV_CVC_ATTRIBUTE_2)); rb_define_const(eXMLError, "SCHEMAV_CVC_ATTRIBUTE_3", INT2NUM(XML_SCHEMAV_CVC_ATTRIBUTE_3)); rb_define_const(eXMLError, "SCHEMAV_CVC_ATTRIBUTE_4", INT2NUM(XML_SCHEMAV_CVC_ATTRIBUTE_4)); rb_define_const(eXMLError, "SCHEMAV_CVC_COMPLEX_TYPE_3_1", INT2NUM(XML_SCHEMAV_CVC_COMPLEX_TYPE_3_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_COMPLEX_TYPE_3_2_1", INT2NUM(XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_COMPLEX_TYPE_3_2_2", INT2NUM(XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2)); rb_define_const(eXMLError, "SCHEMAV_CVC_COMPLEX_TYPE_4", INT2NUM(XML_SCHEMAV_CVC_COMPLEX_TYPE_4)); rb_define_const(eXMLError, "SCHEMAV_CVC_COMPLEX_TYPE_5_1", INT2NUM(XML_SCHEMAV_CVC_COMPLEX_TYPE_5_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_COMPLEX_TYPE_5_2", INT2NUM(XML_SCHEMAV_CVC_COMPLEX_TYPE_5_2)); rb_define_const(eXMLError, "SCHEMAV_ELEMENT_CONTENT", INT2NUM(XML_SCHEMAV_ELEMENT_CONTENT)); rb_define_const(eXMLError, "SCHEMAV_DOCUMENT_ELEMENT_MISSING", INT2NUM(XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING)); rb_define_const(eXMLError, "SCHEMAV_CVC_COMPLEX_TYPE_1", INT2NUM(XML_SCHEMAV_CVC_COMPLEX_TYPE_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_AU", INT2NUM(XML_SCHEMAV_CVC_AU)); rb_define_const(eXMLError, "SCHEMAV_CVC_TYPE_1", INT2NUM(XML_SCHEMAV_CVC_TYPE_1)); rb_define_const(eXMLError, "SCHEMAV_CVC_TYPE_2", INT2NUM(XML_SCHEMAV_CVC_TYPE_2)); #if LIBXML_VERSION >= 20618 rb_define_const(eXMLError, "SCHEMAV_CVC_IDC", INT2NUM(XML_SCHEMAV_CVC_IDC)); rb_define_const(eXMLError, "SCHEMAV_CVC_WILDCARD", INT2NUM(XML_SCHEMAV_CVC_WILDCARD)); #endif #if LIBXML_VERSION >= 20631 rb_define_const(eXMLError, "SCHEMAV_MISC", INT2NUM(XML_SCHEMAV_MISC)); #endif rb_define_const(eXMLError, "XPTR_UNKNOWN_SCHEME", INT2NUM(XML_XPTR_UNKNOWN_SCHEME)); rb_define_const(eXMLError, "XPTR_CHILDSEQ_START", INT2NUM(XML_XPTR_CHILDSEQ_START)); rb_define_const(eXMLError, "XPTR_EVAL_FAILED", INT2NUM(XML_XPTR_EVAL_FAILED)); rb_define_const(eXMLError, "XPTR_EXTRA_OBJECTS", INT2NUM(XML_XPTR_EXTRA_OBJECTS)); rb_define_const(eXMLError, "C14N_CREATE_CTXT", INT2NUM(XML_C14N_CREATE_CTXT)); rb_define_const(eXMLError, "C14N_REQUIRES_UTF8", INT2NUM(XML_C14N_REQUIRES_UTF8)); rb_define_const(eXMLError, "C14N_CREATE_STACK", INT2NUM(XML_C14N_CREATE_STACK)); rb_define_const(eXMLError, "C14N_INVALID_NODE", INT2NUM(XML_C14N_INVALID_NODE)); #if LIBXML_VERSION >= 20619 rb_define_const(eXMLError, "C14N_UNKNOW_NODE", INT2NUM(XML_C14N_UNKNOW_NODE)); rb_define_const(eXMLError, "C14N_RELATIVE_NAMESPACE", INT2NUM(XML_C14N_RELATIVE_NAMESPACE)); #endif rb_define_const(eXMLError, "FTP_PASV_ANSWER", INT2NUM(XML_FTP_PASV_ANSWER)); rb_define_const(eXMLError, "FTP_EPSV_ANSWER", INT2NUM(XML_FTP_EPSV_ANSWER)); rb_define_const(eXMLError, "FTP_ACCNT", INT2NUM(XML_FTP_ACCNT)); #if LIBXML_VERSION >= 20618 rb_define_const(eXMLError, "FTP_URL_SYNTAX", INT2NUM(XML_FTP_URL_SYNTAX)); #endif rb_define_const(eXMLError, "HTTP_URL_SYNTAX", INT2NUM(XML_HTTP_URL_SYNTAX)); rb_define_const(eXMLError, "HTTP_USE_IP", INT2NUM(XML_HTTP_USE_IP)); rb_define_const(eXMLError, "HTTP_UNKNOWN_HOST", INT2NUM(XML_HTTP_UNKNOWN_HOST)); rb_define_const(eXMLError, "SCHEMAP_SRC_SIMPLE_TYPE_1", INT2NUM(XML_SCHEMAP_SRC_SIMPLE_TYPE_1)); rb_define_const(eXMLError, "SCHEMAP_SRC_SIMPLE_TYPE_2", INT2NUM(XML_SCHEMAP_SRC_SIMPLE_TYPE_2)); rb_define_const(eXMLError, "SCHEMAP_SRC_SIMPLE_TYPE_3", INT2NUM(XML_SCHEMAP_SRC_SIMPLE_TYPE_3)); rb_define_const(eXMLError, "SCHEMAP_SRC_SIMPLE_TYPE_4", INT2NUM(XML_SCHEMAP_SRC_SIMPLE_TYPE_4)); rb_define_const(eXMLError, "SCHEMAP_SRC_RESOLVE", INT2NUM(XML_SCHEMAP_SRC_RESOLVE)); rb_define_const(eXMLError, "SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE", INT2NUM(XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE)); rb_define_const(eXMLError, "SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE", INT2NUM(XML_SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE)); rb_define_const(eXMLError, "SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES", INT2NUM(XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES)); rb_define_const(eXMLError, "SCHEMAP_ST_PROPS_CORRECT_1", INT2NUM(XML_SCHEMAP_ST_PROPS_CORRECT_1)); rb_define_const(eXMLError, "SCHEMAP_ST_PROPS_CORRECT_2", INT2NUM(XML_SCHEMAP_ST_PROPS_CORRECT_2)); rb_define_const(eXMLError, "SCHEMAP_ST_PROPS_CORRECT_3", INT2NUM(XML_SCHEMAP_ST_PROPS_CORRECT_3)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_1_1", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_1_1)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_1_2", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_1_2)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_1_3_1", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_1_3_2", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_1_3_2)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_2_1", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_2_1)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_2_3_1_1", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_2_3_1_2", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_2_3_2_1", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_2_3_2_2", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_2_3_2_3", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_2_3_2_4", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_2_3_2_5", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_5)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_3_1", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_3_1)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_3_3_1", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_3_3_1_2", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_3_3_2_2", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_3_3_2_1", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_3_3_2_3", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_3_3_2_4", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_RESTRICTS_3_3_2_5", INT2NUM(XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_5)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_DERIVED_OK_2_1", INT2NUM(XML_SCHEMAP_COS_ST_DERIVED_OK_2_1)); rb_define_const(eXMLError, "SCHEMAP_COS_ST_DERIVED_OK_2_2", INT2NUM(XML_SCHEMAP_COS_ST_DERIVED_OK_2_2)); rb_define_const(eXMLError, "SCHEMAP_S4S_ELEM_NOT_ALLOWED", INT2NUM(XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED)); rb_define_const(eXMLError, "SCHEMAP_S4S_ELEM_MISSING", INT2NUM(XML_SCHEMAP_S4S_ELEM_MISSING)); rb_define_const(eXMLError, "SCHEMAP_S4S_ATTR_NOT_ALLOWED", INT2NUM(XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED)); rb_define_const(eXMLError, "SCHEMAP_S4S_ATTR_MISSING", INT2NUM(XML_SCHEMAP_S4S_ATTR_MISSING)); rb_define_const(eXMLError, "SCHEMAP_S4S_ATTR_INVALID_VALUE", INT2NUM(XML_SCHEMAP_S4S_ATTR_INVALID_VALUE)); rb_define_const(eXMLError, "SCHEMAP_SRC_ELEMENT_1", INT2NUM(XML_SCHEMAP_SRC_ELEMENT_1)); rb_define_const(eXMLError, "SCHEMAP_SRC_ELEMENT_2_1", INT2NUM(XML_SCHEMAP_SRC_ELEMENT_2_1)); rb_define_const(eXMLError, "SCHEMAP_SRC_ELEMENT_2_2", INT2NUM(XML_SCHEMAP_SRC_ELEMENT_2_2)); rb_define_const(eXMLError, "SCHEMAP_SRC_ELEMENT_3", INT2NUM(XML_SCHEMAP_SRC_ELEMENT_3)); rb_define_const(eXMLError, "SCHEMAP_P_PROPS_CORRECT_1", INT2NUM(XML_SCHEMAP_P_PROPS_CORRECT_1)); rb_define_const(eXMLError, "SCHEMAP_P_PROPS_CORRECT_2_1", INT2NUM(XML_SCHEMAP_P_PROPS_CORRECT_2_1)); rb_define_const(eXMLError, "SCHEMAP_P_PROPS_CORRECT_2_2", INT2NUM(XML_SCHEMAP_P_PROPS_CORRECT_2_2)); rb_define_const(eXMLError, "SCHEMAP_E_PROPS_CORRECT_2", INT2NUM(XML_SCHEMAP_E_PROPS_CORRECT_2)); rb_define_const(eXMLError, "SCHEMAP_E_PROPS_CORRECT_3", INT2NUM(XML_SCHEMAP_E_PROPS_CORRECT_3)); rb_define_const(eXMLError, "SCHEMAP_E_PROPS_CORRECT_4", INT2NUM(XML_SCHEMAP_E_PROPS_CORRECT_4)); rb_define_const(eXMLError, "SCHEMAP_E_PROPS_CORRECT_5", INT2NUM(XML_SCHEMAP_E_PROPS_CORRECT_5)); rb_define_const(eXMLError, "SCHEMAP_E_PROPS_CORRECT_6", INT2NUM(XML_SCHEMAP_E_PROPS_CORRECT_6)); rb_define_const(eXMLError, "SCHEMAP_SRC_INCLUDE", INT2NUM(XML_SCHEMAP_SRC_INCLUDE)); rb_define_const(eXMLError, "SCHEMAP_SRC_ATTRIBUTE_1", INT2NUM(XML_SCHEMAP_SRC_ATTRIBUTE_1)); rb_define_const(eXMLError, "SCHEMAP_SRC_ATTRIBUTE_2", INT2NUM(XML_SCHEMAP_SRC_ATTRIBUTE_2)); rb_define_const(eXMLError, "SCHEMAP_SRC_ATTRIBUTE_3_1", INT2NUM(XML_SCHEMAP_SRC_ATTRIBUTE_3_1)); rb_define_const(eXMLError, "SCHEMAP_SRC_ATTRIBUTE_3_2", INT2NUM(XML_SCHEMAP_SRC_ATTRIBUTE_3_2)); rb_define_const(eXMLError, "SCHEMAP_SRC_ATTRIBUTE_4", INT2NUM(XML_SCHEMAP_SRC_ATTRIBUTE_4)); rb_define_const(eXMLError, "SCHEMAP_NO_XMLNS", INT2NUM(XML_SCHEMAP_NO_XMLNS)); rb_define_const(eXMLError, "SCHEMAP_NO_XSI", INT2NUM(XML_SCHEMAP_NO_XSI)); rb_define_const(eXMLError, "SCHEMAP_COS_VALID_DEFAULT_1", INT2NUM(XML_SCHEMAP_COS_VALID_DEFAULT_1)); rb_define_const(eXMLError, "SCHEMAP_COS_VALID_DEFAULT_2_1", INT2NUM(XML_SCHEMAP_COS_VALID_DEFAULT_2_1)); rb_define_const(eXMLError, "SCHEMAP_COS_VALID_DEFAULT_2_2_1", INT2NUM(XML_SCHEMAP_COS_VALID_DEFAULT_2_2_1)); rb_define_const(eXMLError, "SCHEMAP_COS_VALID_DEFAULT_2_2_2", INT2NUM(XML_SCHEMAP_COS_VALID_DEFAULT_2_2_2)); rb_define_const(eXMLError, "SCHEMAP_CVC_SIMPLE_TYPE", INT2NUM(XML_SCHEMAP_CVC_SIMPLE_TYPE)); rb_define_const(eXMLError, "SCHEMAP_COS_CT_EXTENDS_1_1", INT2NUM(XML_SCHEMAP_COS_CT_EXTENDS_1_1)); rb_define_const(eXMLError, "SCHEMAP_SRC_IMPORT_1_1", INT2NUM(XML_SCHEMAP_SRC_IMPORT_1_1)); rb_define_const(eXMLError, "SCHEMAP_SRC_IMPORT_1_2", INT2NUM(XML_SCHEMAP_SRC_IMPORT_1_2)); rb_define_const(eXMLError, "SCHEMAP_SRC_IMPORT_2", INT2NUM(XML_SCHEMAP_SRC_IMPORT_2)); rb_define_const(eXMLError, "SCHEMAP_SRC_IMPORT_2_1", INT2NUM(XML_SCHEMAP_SRC_IMPORT_2_1)); rb_define_const(eXMLError, "SCHEMAP_SRC_IMPORT_2_2", INT2NUM(XML_SCHEMAP_SRC_IMPORT_2_2)); rb_define_const(eXMLError, "SCHEMAP_INTERNAL", INT2NUM(XML_SCHEMAP_INTERNAL)); rb_define_const(eXMLError, "SCHEMAP_NOT_DETERMINISTIC", INT2NUM(XML_SCHEMAP_NOT_DETERMINISTIC)); rb_define_const(eXMLError, "SCHEMAP_SRC_ATTRIBUTE_GROUP_1", INT2NUM(XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_1)); rb_define_const(eXMLError, "SCHEMAP_SRC_ATTRIBUTE_GROUP_2", INT2NUM(XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_2)); rb_define_const(eXMLError, "SCHEMAP_SRC_ATTRIBUTE_GROUP_3", INT2NUM(XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3)); rb_define_const(eXMLError, "SCHEMAP_MG_PROPS_CORRECT_1", INT2NUM(XML_SCHEMAP_MG_PROPS_CORRECT_1)); rb_define_const(eXMLError, "SCHEMAP_MG_PROPS_CORRECT_2", INT2NUM(XML_SCHEMAP_MG_PROPS_CORRECT_2)); rb_define_const(eXMLError, "SCHEMAP_SRC_CT_1", INT2NUM(XML_SCHEMAP_SRC_CT_1)); rb_define_const(eXMLError, "SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3", INT2NUM(XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3)); rb_define_const(eXMLError, "SCHEMAP_AU_PROPS_CORRECT_2", INT2NUM(XML_SCHEMAP_AU_PROPS_CORRECT_2)); rb_define_const(eXMLError, "SCHEMAP_A_PROPS_CORRECT_2", INT2NUM(XML_SCHEMAP_A_PROPS_CORRECT_2)); #if LIBXML_VERSION >= 20620 rb_define_const(eXMLError, "SCHEMAP_C_PROPS_CORRECT", INT2NUM(XML_SCHEMAP_C_PROPS_CORRECT)); #endif #if LIBXML_VERSION >= 20621 rb_define_const(eXMLError, "SCHEMAP_SRC_REDEFINE", INT2NUM(XML_SCHEMAP_SRC_REDEFINE)); rb_define_const(eXMLError, "SCHEMAP_SRC_IMPORT", INT2NUM(XML_SCHEMAP_SRC_IMPORT)); rb_define_const(eXMLError, "SCHEMAP_WARN_SKIP_SCHEMA", INT2NUM(XML_SCHEMAP_WARN_SKIP_SCHEMA)); rb_define_const(eXMLError, "SCHEMAP_WARN_UNLOCATED_SCHEMA", INT2NUM(XML_SCHEMAP_WARN_UNLOCATED_SCHEMA)); rb_define_const(eXMLError, "SCHEMAP_WARN_ATTR_REDECL_PROH", INT2NUM(XML_SCHEMAP_WARN_ATTR_REDECL_PROH)); rb_define_const(eXMLError, "SCHEMAP_WARN_ATTR_POINTLESS_PROH", INT2NUM(XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH)); #endif #if LIBXML_VERSION >= 20623 rb_define_const(eXMLError, "SCHEMAP_AG_PROPS_CORRECT", INT2NUM(XML_SCHEMAP_AG_PROPS_CORRECT)); rb_define_const(eXMLError, "SCHEMAP_COS_CT_EXTENDS_1_2", INT2NUM(XML_SCHEMAP_COS_CT_EXTENDS_1_2)); rb_define_const(eXMLError, "SCHEMAP_AU_PROPS_CORRECT", INT2NUM(XML_SCHEMAP_AU_PROPS_CORRECT)); rb_define_const(eXMLError, "SCHEMAP_A_PROPS_CORRECT_3", INT2NUM(XML_SCHEMAP_A_PROPS_CORRECT_3)); rb_define_const(eXMLError, "SCHEMAP_COS_ALL_LIMITED", INT2NUM(XML_SCHEMAP_COS_ALL_LIMITED)); #endif #if LIBXML_VERSION >= 20632 rb_define_const(eXMLError, "SCHEMATRONV_ASSERT", INT2NUM(XML_SCHEMATRONV_ASSERT)); rb_define_const(eXMLError, "SCHEMATRONV_REPORT", INT2NUM(XML_SCHEMATRONV_REPORT)); #endif #if LIBXML_VERSION >= 20618 rb_define_const(eXMLError, "MODULE_OPEN", INT2NUM(XML_MODULE_OPEN)); rb_define_const(eXMLError, "MODULE_CLOSE", INT2NUM(XML_MODULE_CLOSE)); #endif rb_define_const(eXMLError, "CHECK_FOUND_ELEMENT", INT2NUM(XML_CHECK_FOUND_ELEMENT)); rb_define_const(eXMLError, "CHECK_FOUND_ATTRIBUTE", INT2NUM(XML_CHECK_FOUND_ATTRIBUTE)); rb_define_const(eXMLError, "CHECK_FOUND_TEXT", INT2NUM(XML_CHECK_FOUND_TEXT)); rb_define_const(eXMLError, "CHECK_FOUND_CDATA",INT2NUM(XML_CHECK_FOUND_CDATA)); rb_define_const(eXMLError, "CHECK_FOUND_ENTITYREF", INT2NUM(XML_CHECK_FOUND_ENTITYREF)); rb_define_const(eXMLError, "CHECK_FOUND_ENTITY", INT2NUM(XML_CHECK_FOUND_ENTITY)); rb_define_const(eXMLError, "CHECK_FOUND_PI", INT2NUM(XML_CHECK_FOUND_PI)); rb_define_const(eXMLError, "CHECK_FOUND_COMMENT", INT2NUM(XML_CHECK_FOUND_COMMENT)); rb_define_const(eXMLError, "CHECK_FOUND_DOCTYPE", INT2NUM(XML_CHECK_FOUND_DOCTYPE)); rb_define_const(eXMLError, "CHECK_FOUND_FRAGMENT", INT2NUM(XML_CHECK_FOUND_FRAGMENT)); rb_define_const(eXMLError, "CHECK_FOUND_NOTATION", INT2NUM(XML_CHECK_FOUND_NOTATION)); rb_define_const(eXMLError, "CHECK_UNKNOWN_NODE", INT2NUM(XML_CHECK_UNKNOWN_NODE)); rb_define_const(eXMLError, "CHECK_ENTITY_TYPE", INT2NUM(XML_CHECK_ENTITY_TYPE)); rb_define_const(eXMLError, "CHECK_NO_PARENT", INT2NUM(XML_CHECK_NO_PARENT)); rb_define_const(eXMLError, "CHECK_NO_DOC", INT2NUM(XML_CHECK_NO_DOC)); rb_define_const(eXMLError, "CHECK_NO_NAME", INT2NUM(XML_CHECK_NO_NAME)); rb_define_const(eXMLError, "CHECK_NO_ELEM", INT2NUM(XML_CHECK_NO_ELEM)); rb_define_const(eXMLError, "CHECK_WRONG_DOC", INT2NUM(XML_CHECK_WRONG_DOC)); rb_define_const(eXMLError, "CHECK_NO_PREV", INT2NUM(XML_CHECK_NO_PREV)); rb_define_const(eXMLError, "CHECK_WRONG_PREV", INT2NUM(XML_CHECK_WRONG_PREV)); rb_define_const(eXMLError, "CHECK_NO_NEXT", INT2NUM(XML_CHECK_NO_NEXT)); rb_define_const(eXMLError, "CHECK_WRONG_NEXT", INT2NUM(XML_CHECK_WRONG_NEXT)); rb_define_const(eXMLError, "CHECK_NOT_DTD", INT2NUM(XML_CHECK_NOT_DTD)); rb_define_const(eXMLError, "CHECK_NOT_ATTR", INT2NUM(XML_CHECK_NOT_ATTR)); rb_define_const(eXMLError, "CHECK_NOT_ATTR_DECL", INT2NUM(XML_CHECK_NOT_ATTR_DECL)); rb_define_const(eXMLError, "CHECK_NOT_ELEM_DECL", INT2NUM(XML_CHECK_NOT_ELEM_DECL)); rb_define_const(eXMLError, "CHECK_NOT_ENTITY_DECL", INT2NUM(XML_CHECK_NOT_ENTITY_DECL)); rb_define_const(eXMLError, "CHECK_NOT_NS_DECL", INT2NUM(XML_CHECK_NOT_NS_DECL)); rb_define_const(eXMLError, "CHECK_NO_HREF", INT2NUM(XML_CHECK_NO_HREF)); rb_define_const(eXMLError, "CHECK_WRONG_PARENT", INT2NUM(XML_CHECK_WRONG_PARENT)); rb_define_const(eXMLError, "CHECK_NS_SCOPE", INT2NUM(XML_CHECK_NS_SCOPE)); rb_define_const(eXMLError, "CHECK_NS_ANCESTOR", INT2NUM(XML_CHECK_NS_ANCESTOR)); rb_define_const(eXMLError, "CHECK_NOT_UTF8", INT2NUM(XML_CHECK_NOT_UTF8)); rb_define_const(eXMLError, "CHECK_NO_DICT", INT2NUM(XML_CHECK_NO_DICT)); rb_define_const(eXMLError, "CHECK_NOT_NCNAME", INT2NUM(XML_CHECK_NOT_NCNAME)); rb_define_const(eXMLError, "CHECK_OUTSIDE_DICT", INT2NUM(XML_CHECK_OUTSIDE_DICT)); rb_define_const(eXMLError, "CHECK_WRONG_NAME", INT2NUM(XML_CHECK_WRONG_NAME)); #if LIBXML_VERSION >= 20621 rb_define_const(eXMLError, "CHECK_NAME_NOT_NULL", INT2NUM(XML_CHECK_NAME_NOT_NULL)); rb_define_const(eXMLError, "I18N_NO_NAME", INT2NUM(XML_I18N_NO_NAME)); rb_define_const(eXMLError, "I18N_NO_HANDLER", INT2NUM(XML_I18N_NO_HANDLER)); rb_define_const(eXMLError, "I18N_EXCESS_HANDLER", INT2NUM(XML_I18N_EXCESS_HANDLER)); rb_define_const(eXMLError, "I18N_CONV_FAILED", INT2NUM(XML_I18N_CONV_FAILED)); rb_define_const(eXMLError, "I18N_NO_OUTPUT", INT2NUM(XML_I18N_NO_OUTPUT)); #endif } libxml-ruby-3.2.1/ext/libxml/ruby_xml_relaxng.h0000644000004100000410000000023413760147770021647 0ustar www-datawww-data#ifndef __RXML_RELAXNG__ #define __RXML_RELAXNG__ #include extern VALUE cXMLRelaxNG; void rxml_init_relaxng(void); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_html_parser.c0000644000004100000410000000474213760147770022532 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #include "ruby_libxml.h" /* Document-class: LibXML::XML::HTMLParser * * The HTML parser implements an HTML 4.0 non-verifying parser with an API * compatible with the XML::Parser. In contrast with the XML::Parser, * it can parse "real world" HTML, even if it severely broken from a * specification point of view. * * The HTML parser creates an in-memory document object * that consist of any number of XML::Node instances. This is simple * and powerful model, but has the major limitation that the size of * the document that can be processed is limited by the amount of * memory available. * * Using the html parser is simple: * * parser = XML::HTMLParser.file('my_file') * doc = parser.parse * * You can also parse documents (see XML::HTMLParser.document), * strings (see XML::HTMLParser.string) and io objects (see * XML::HTMLParser.io). */ VALUE cXMLHtmlParser; static ID CONTEXT_ATTR; /* call-seq: * XML::HTMLParser.initialize -> parser * * Initializes a new parser instance with no pre-determined source. */ static VALUE rxml_html_parser_initialize(int argc, VALUE *argv, VALUE self) { VALUE context = Qnil; rb_scan_args(argc, argv, "01", &context); if (context == Qnil) { rb_raise(rb_eArgError, "An instance of a XML::Parser::Context must be passed to XML::HTMLParser.new"); } rb_ivar_set(self, CONTEXT_ATTR, context); return self; } /* * call-seq: * parser.parse -> XML::Document * * Parse the input XML and create an XML::Document with * it's content. If an error occurs, XML::Parser::ParseError * is thrown. */ static VALUE rxml_html_parser_parse(VALUE self) { xmlParserCtxtPtr ctxt; VALUE context = rb_ivar_get(self, CONTEXT_ATTR); Data_Get_Struct(context, xmlParserCtxt, ctxt); if (htmlParseDocument(ctxt) == -1 && ! ctxt->recovery) { rxml_raise(&ctxt->lastError); } rb_funcall(context, rb_intern("close"), 0); return rxml_document_wrap(ctxt->myDoc); } void rxml_init_html_parser(void) { CONTEXT_ATTR = rb_intern("@context"); cXMLHtmlParser = rb_define_class_under(mXML, "HTMLParser", rb_cObject); /* Atributes */ rb_define_attr(cXMLHtmlParser, "input", 1, 0); /* Instance methods */ rb_define_method(cXMLHtmlParser, "initialize", rxml_html_parser_initialize, -1); rb_define_method(cXMLHtmlParser, "parse", rxml_html_parser_parse, 0); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_attr.h0000644000004100000410000000050213760147770021157 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_ATTR__ #define __RXML_ATTR__ extern VALUE cXMLAttr; void rxml_init_attr(void); VALUE rxml_attr_wrap(xmlAttrPtr xattr); VALUE rxml_attr_value_get(VALUE self); VALUE rxml_attr_value_set(VALUE self, VALUE val); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml_attr.c0000644000004100000410000001776513760147770021175 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ /* * Document-class: LibXML::XML::Attr * * Provides access to an attribute defined on an element. * * Basic Usage: * * require 'test_helper' * * doc = XML::Document.new() * attribute = doc.root.attributes.get_attribute_ns('http://www.w3.org/1999/xlink', 'href') * attribute.name == 'href' * attribute.value == 'http://www.mydocument.com' * attribute.remove! */ /* Attributes are owned and freed by their nodes. Thus, its easier for the ruby bindings to not manage attribute memory management. This does mean that accessing a particular attribute multiple times will return multiple different ruby objects. Since we are not using free this works out fine. Previous versions of the bindings had a one to one mapping between ruby object and xml attribute, but that could result in segfaults because the ruby object could be gc'ed. In theory the mark method on the parent node could prevent that, but if an attribute is returned using an xpath statement then the node would never by surfaced to ruby and the mark method never called. */ #include "ruby_libxml.h" #include "ruby_xml_attr.h" VALUE cXMLAttr; void rxml_attr_mark(xmlAttrPtr xattr) { /* This can happen if Ruby does a GC run after creating the new attribute but before initializing it. */ if (xattr != NULL) rxml_node_mark((xmlNodePtr) xattr); } VALUE rxml_attr_wrap(xmlAttrPtr xattr) { return Data_Wrap_Struct(cXMLAttr, rxml_attr_mark, NULL, xattr); } static VALUE rxml_attr_alloc(VALUE klass) { return Data_Wrap_Struct(klass, rxml_attr_mark, NULL, NULL); } /* * call-seq: * attr.initialize(node, "name", "value") * * Creates a new attribute for the node. * * node: The XML::Node that will contain the attribute * name: The name of the attribute * value: The value of the attribute * * attr = XML::Attr.new(doc.root, 'name', 'libxml') */ static VALUE rxml_attr_initialize(int argc, VALUE *argv, VALUE self) { VALUE node = argv[0]; VALUE name = argv[1]; VALUE value = argv[2]; VALUE ns = (argc == 4 ? argv[3] : Qnil); xmlNodePtr xnode; xmlAttrPtr xattr; if (argc < 3 || argc > 4) rb_raise(rb_eArgError, "Wrong number of arguments (3 or 4)"); Check_Type(name, T_STRING); Check_Type(value, T_STRING); Data_Get_Struct(node, xmlNode, xnode); if (xnode->type != XML_ELEMENT_NODE) rb_raise(rb_eArgError, "Attributes can only be created on element nodes."); if (NIL_P(ns)) { xattr = xmlNewProp(xnode, (xmlChar*)StringValuePtr(name), (xmlChar*)StringValuePtr(value)); } else { xmlNsPtr xns; Data_Get_Struct(ns, xmlNs, xns); xattr = xmlNewNsProp(xnode, xns, (xmlChar*)StringValuePtr(name), (xmlChar*)StringValuePtr(value)); } if (!xattr) rb_raise(rb_eRuntimeError, "Could not create attribute."); DATA_PTR( self) = xattr; return self; } /* * call-seq: * attr.child -> node * * Obtain this attribute's child attribute(s). */ static VALUE rxml_attr_child_get(VALUE self) { xmlAttrPtr xattr; Data_Get_Struct(self, xmlAttr, xattr); if (xattr->children == NULL) return Qnil; else return rxml_node_wrap((xmlNodePtr) xattr->children); } /* * call-seq: * attr.doc -> XML::Document * * Returns this attribute's document. * * doc.root.attributes.get_attribute('name').doc == doc */ static VALUE rxml_attr_doc_get(VALUE self) { xmlAttrPtr xattr; Data_Get_Struct(self, xmlAttr, xattr); if (xattr->doc == NULL) return Qnil; else return rxml_document_wrap(xattr->doc); } /* * call-seq: * attr.last -> node * * Obtain the last attribute. */ static VALUE rxml_attr_last_get(VALUE self) { xmlAttrPtr xattr; Data_Get_Struct(self, xmlAttr, xattr); if (xattr->last == NULL) return Qnil; else return rxml_node_wrap(xattr->last); } /* * call-seq: * attr.name -> "name" * * Obtain this attribute's name. */ static VALUE rxml_attr_name_get(VALUE self) { xmlAttrPtr xattr; Data_Get_Struct(self, xmlAttr, xattr); if (xattr->name == NULL) return Qnil; else return rxml_new_cstr( xattr->name, NULL); } /* * call-seq: * attr.next -> node * * Obtain the next attribute. */ static VALUE rxml_attr_next_get(VALUE self) { xmlAttrPtr xattr; Data_Get_Struct(self, xmlAttr, xattr); if (xattr->next == NULL) return Qnil; else return rxml_attr_wrap(xattr->next); } /* * call-seq: * attr.node_type -> num * * Obtain this node's type identifier. */ static VALUE rxml_attr_node_type(VALUE self) { xmlAttrPtr xattr; Data_Get_Struct(self, xmlAttr, xattr); return INT2NUM(xattr->type); } /* * call-seq: * attr.ns -> namespace * * Obtain this attribute's associated XML::NS, if any. */ static VALUE rxml_attr_ns_get(VALUE self) { xmlAttrPtr xattr; Data_Get_Struct(self, xmlAttr, xattr); if (xattr->ns == NULL) return Qnil; else return rxml_namespace_wrap(xattr->ns); } /* * call-seq: * attr.parent -> node * * Obtain this attribute node's parent. */ static VALUE rxml_attr_parent_get(VALUE self) { xmlAttrPtr xattr; Data_Get_Struct(self, xmlAttr, xattr); if (xattr->parent == NULL) return Qnil; else return rxml_node_wrap(xattr->parent); } /* * call-seq: * attr.prev -> node * * Obtain the previous attribute. */ static VALUE rxml_attr_prev_get(VALUE self) { xmlAttrPtr xattr; Data_Get_Struct(self, xmlAttr, xattr); if (xattr->prev == NULL) return Qnil; else return rxml_attr_wrap(xattr->prev); } /* * call-seq: * attr.remove! -> nil * * Removes this attribute from it's parent. Note * the attribute and its content is freed and can * no longer be used. If you try to use it you * will get a segmentation fault. */ static VALUE rxml_attr_remove_ex(VALUE self) { xmlAttrPtr xattr; Data_Get_Struct(self, xmlAttr, xattr); xmlRemoveProp(xattr); RDATA(self)->data = NULL; RDATA(self)->dfree = NULL; RDATA(self)->dmark = NULL; return Qnil; } /* * call-seq: * attr.value -> "value" * * Obtain the value of this attribute. */ VALUE rxml_attr_value_get(VALUE self) { xmlAttrPtr xattr; xmlChar *value; VALUE result = Qnil; Data_Get_Struct(self, xmlAttr, xattr); value = xmlNodeGetContent((xmlNodePtr)xattr); if (value != NULL) { result = rxml_new_cstr( value, NULL); xmlFree(value); } return result; } /* * call-seq: * attr.value = "value" * * Sets the value of this attribute. */ VALUE rxml_attr_value_set(VALUE self, VALUE val) { xmlAttrPtr xattr; Check_Type(val, T_STRING); Data_Get_Struct(self, xmlAttr, xattr); if (xattr->ns) xmlSetNsProp(xattr->parent, xattr->ns, xattr->name, (xmlChar*) StringValuePtr(val)); else xmlSetProp(xattr->parent, xattr->name, (xmlChar*) StringValuePtr(val)); return (self); } void rxml_init_attr(void) { cXMLAttr = rb_define_class_under(mXML, "Attr", rb_cObject); rb_define_alloc_func(cXMLAttr, rxml_attr_alloc); rb_define_method(cXMLAttr, "initialize", rxml_attr_initialize, -1); rb_define_method(cXMLAttr, "child", rxml_attr_child_get, 0); rb_define_method(cXMLAttr, "doc", rxml_attr_doc_get, 0); rb_define_method(cXMLAttr, "last", rxml_attr_last_get, 0); rb_define_method(cXMLAttr, "name", rxml_attr_name_get, 0); rb_define_method(cXMLAttr, "next", rxml_attr_next_get, 0); rb_define_method(cXMLAttr, "node_type", rxml_attr_node_type, 0); rb_define_method(cXMLAttr, "ns", rxml_attr_ns_get, 0); rb_define_method(cXMLAttr, "parent", rxml_attr_parent_get, 0); rb_define_method(cXMLAttr, "prev", rxml_attr_prev_get, 0); rb_define_method(cXMLAttr, "remove!", rxml_attr_remove_ex, 0); rb_define_method(cXMLAttr, "value", rxml_attr_value_get, 0); rb_define_method(cXMLAttr, "value=", rxml_attr_value_set, 1); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_xpointer.h0000644000004100000410000000041113760147770022054 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_XPOINTER__ #define __RXML_XPOINTER__ extern VALUE cXMLXPointer; void rxml_init_xpointer(void); VALUE rxml_xpointer_point2(VALUE node, VALUE xptr_str); #endif libxml-ruby-3.2.1/ext/libxml/ruby_xml.c0000644000004100000410000005446613760147770020142 0ustar www-datawww-data#include "ruby_libxml.h" #include "ruby_xml.h" VALUE mXML; /* * call-seq: * XML.catalog_dump -> true * * Dump all the global catalog content stdout. */ static VALUE rxml_catalog_dump(VALUE self) { xmlCatalogDump(stdout); return (Qtrue); } /* * call-seq: * XML.catalog_remove(catalog) -> true * * Remove the specified resource catalog. */ static VALUE rxml_catalog_remove(VALUE self, VALUE cat) { Check_Type(cat, T_STRING); xmlCatalogRemove((xmlChar *) StringValuePtr(cat)); return (Qtrue); } /* * call-seq: * XML.check_lib_versions -> true * * Check LIBXML version matches version the bindings * were compiled to. Throws an exception if not. */ static VALUE rxml_check_lib_versions(VALUE klass) { xmlCheckVersion(LIBXML_VERSION); return (Qtrue); } /* * call-seq: * XML.enabled_automata? -> (true|false) * * Determine whether libxml regexp automata support is enabled. */ static VALUE rxml_enabled_automata_q(VALUE klass) { #ifdef LIBXML_AUTOMATA_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_c14n? -> (true|false) * * Determine whether libxml 'canonical XML' support is enabled. * See "Canonical XML" (http://www.w3.org/TR/xml-c14n) */ static VALUE rxml_enabled_c14n_q(VALUE klass) { #ifdef LIBXML_C14N_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_catalog? -> (true|false) * * Determine whether libxml resource catalog support is enabled. */ static VALUE rxml_enabled_catalog_q(VALUE klass) { #ifdef LIBXML_CATALOG_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_debug? -> (true|false) * * Determine whether libxml debugging support is enabled. */ static VALUE rxml_enabled_debug_q(VALUE klass) { #ifdef LIBXML_DEBUG_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_docbook? -> (true|false) * * Determine whether libxml docbook support is enabled. */ static VALUE rxml_enabled_docbook_q(VALUE klass) { #ifdef LIBXML_DOCB_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_ftp? -> (true|false) * * Determine whether libxml ftp client support is enabled. */ static VALUE rxml_enabled_ftp_q(VALUE klass) { #ifdef LIBXML_FTP_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_http? -> (true|false) * * Determine whether libxml http client support is enabled. */ static VALUE rxml_enabled_http_q(VALUE klass) { #ifdef LIBXML_HTTP_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_html? -> (true|false) * * Determine whether libxml html support is enabled. */ static VALUE rxml_enabled_html_q(VALUE klass) { #ifdef LIBXML_HTML_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_iconv? -> (true|false) * * Determine whether libxml iconv support is enabled. */ static VALUE rxml_enabled_iconv_q(VALUE klass) { #ifdef LIBXML_ICONV_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_memory_debug? -> (true|false) * * Determine whether libxml memory location debugging support * is enabled. */ static VALUE rxml_enabled_memory_debug_location_q(VALUE klass) { #ifdef DEBUG_MEMORY_LOCATION return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_regexp? -> (true|false) * * Determine whether libxml regular expression support is enabled. */ static VALUE rxml_enabled_regexp_q(VALUE klass) { #ifdef LIBXML_REGEXP_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_schemas? -> (true|false) * * Determine whether libxml schema support is enabled. */ static VALUE rxml_enabled_schemas_q(VALUE klass) { #ifdef LIBXML_SCHEMAS_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_thread? -> (true|false) * * Determine whether thread-safe semantics support for libxml is enabled and * is used by this ruby extension. Threading support in libxml uses pthread * on Unix-like systems and Win32 threads on Windows. */ static VALUE rxml_enabled_thread_q(VALUE klass) { /* This won't be defined unless this code is compiled with _REENTRANT or __MT__ * defined or the compiler is in C99 mode. * * Note the relevant portion libxml/xmlversion.h on a thread-enabled build: * * #if defined(_REENTRANT) || defined(__MT__) || \ * (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L)) * #define LIBXML_THREAD_ENABLED * #endif * */ #ifdef LIBXML_THREAD_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_unicode? -> (true|false) * * Determine whether libxml unicode support is enabled. */ static VALUE rxml_enabled_unicode_q(VALUE klass) { #ifdef LIBXML_UNICODE_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_xinclude? -> (true|false) * * Determine whether libxml xinclude support is enabled. */ static VALUE rxml_enabled_xinclude_q(VALUE klass) { #ifdef LIBXML_XINCLUDE_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_xpath? -> (true|false) * * Determine whether libxml xpath support is enabled. */ static VALUE rxml_enabled_xpath_q(VALUE klass) { #ifdef LIBXML_XPATH_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_xpointer? -> (true|false) * * Determine whether libxml xpointer support is enabled. */ static VALUE rxml_enabled_xpointer_q(VALUE klass) { #ifdef LIBXML_XPTR_ENABLED return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.enabled_zlib? -> (true|false) * * Determine whether libxml zlib support is enabled. */ static VALUE rxml_enabled_zlib_q(VALUE klass) { #ifdef HAVE_ZLIB_H return(Qtrue); #else return (Qfalse); #endif } /* * call-seq: * XML.debug_entities -> (true|false) * * Determine whether included-entity debugging is enabled. * (Requires Libxml to be compiled with debugging support) */ static VALUE rxml_debug_entities_get(VALUE klass) { #ifdef LIBXML_DEBUG_ENABLED if (xmlParserDebugEntities) return(Qtrue); else return(Qfalse); #else rb_warn("libxml was compiled with debugging turned off"); return (Qfalse); #endif } /* * call-seq: * XML.debug_entities = true|false * * Enable or disable included-entity debugging. * (Requires Libxml to be compiled with debugging support) */ static VALUE rxml_debug_entities_set(VALUE klass, VALUE value) { #ifdef LIBXML_DEBUG_ENABLED if (value == Qfalse) { xmlParserDebugEntities = 0; return(Qfalse); } else { xmlParserDebugEntities = 1; return(Qtrue); } #else rb_warn("libxml was compiled with debugging turned off"); #endif } /* * call-seq: * XML.default_keep_blanks -> (true|false) * * Determine whether parsers retain whitespace by default. */ static VALUE rxml_default_keep_blanks_get(VALUE klass) { if (xmlKeepBlanksDefaultValue) return (Qtrue); else return (Qfalse); } /* * call-seq: * XML.default_keep_blanks = true|false * * Controls whether parsers retain whitespace by default. */ static VALUE rxml_default_keep_blanks_set(VALUE klass, VALUE value) { if (value == Qfalse) { xmlKeepBlanksDefaultValue = 0; return (Qfalse); } else if (value == Qtrue) { xmlKeepBlanksDefaultValue = 1; return (Qtrue); } else { rb_raise(rb_eArgError, "Invalid argument, must be a boolean"); } } /* * call-seq: * XML.default_load_external_dtd -> (true|false) * * Determine whether parsers load external DTDs by default. */ static VALUE rxml_default_load_external_dtd_get(VALUE klass) { if (xmlLoadExtDtdDefaultValue) return (Qtrue); else return (Qfalse); } /* * call-seq: * XML.default_load_external_dtd = true|false * * Controls whether parsers load external DTDs by default. */ static VALUE rxml_default_load_external_dtd_set(VALUE klass, VALUE value) { if (value == Qfalse) { xmlLoadExtDtdDefaultValue = 0; return (Qfalse); } else { xmlLoadExtDtdDefaultValue = 1; return (Qtrue); } } /* * call-seq: * XML.default_line_numbers -> (true|false) * * Determine whether parsers retain line-numbers by default. */ static VALUE rxml_default_line_numbers_get(VALUE klass) { if (xmlLineNumbersDefaultValue) return (Qtrue); else return (Qfalse); } /* * call-seq: * XML.default_line_numbers = true|false * * Controls whether parsers retain line-numbers by default. */ static VALUE rxml_default_line_numbers_set(VALUE klass, VALUE value) { if (value == Qfalse) { xmlLineNumbersDefault(0); return (Qfalse); } else { xmlLineNumbersDefault(1); return (Qtrue); } } int rxml_libxml_default_options() { int options = 0; if (xmlLoadExtDtdDefaultValue) options |= XML_PARSE_DTDLOAD; if (xmlDoValidityCheckingDefaultValue) options |= XML_PARSE_DTDVALID; if (!xmlKeepBlanksDefaultValue) options |= XML_PARSE_NOBLANKS; if (xmlSubstituteEntitiesDefaultValue) options |= XML_PARSE_NOENT; if (!xmlGetWarningsDefaultValue) options |= XML_PARSE_NOWARNING; if (xmlPedanticParserDefaultValue) options |= XML_PARSE_PEDANTIC; return options; } /* * call-seq: * XML.default_options -> int * * Returns an integer that summarize libxml2's default options. */ static VALUE rxml_default_options_get(VALUE klass) { int options = rxml_libxml_default_options(); return INT2NUM(options); } /* * call-seq: * XML.default_pedantic_parser -> (true|false) * * Determine whether parsers are pedantic by default. */ static VALUE rxml_default_pedantic_parser_get(VALUE klass) { if (xmlPedanticParserDefaultValue) return (Qtrue); else return (Qfalse); } /* * call-seq: * XML.default_pedantic_parser = true|false * * Controls whether parsers are pedantic by default. */ static VALUE rxml_default_pedantic_parser_set(VALUE klass, VALUE value) { if (value == Qfalse) { xmlPedanticParserDefault(0); return (Qfalse); } else { xmlPedanticParserDefault(1); return (Qtrue); } } /* * call-seq: * XML.default_substitute_entities -> (true|false) * * Determine whether parsers perform inline entity substitution * (for external entities) by default. */ static VALUE rxml_default_substitute_entities_get(VALUE klass) { if (xmlSubstituteEntitiesDefaultValue) return (Qtrue); else return (Qfalse); } /* * call-seq: * XML.default_substitute_entities = true|false * * Controls whether parsers perform inline entity substitution * (for external entities) by default. */ static VALUE rxml_default_substitute_entities_set(VALUE klass, VALUE value) { if (value == Qfalse) { xmlSubstituteEntitiesDefault(0); return (Qfalse); } else { xmlSubstituteEntitiesDefault(1); return (Qtrue); } } /* * call-seq: * XML.default_tree_indent_string -> "string" * * Obtain the default string used by parsers to indent the XML tree * for output. */ static VALUE rxml_default_tree_indent_string_get(VALUE klass) { if (xmlTreeIndentString == NULL) return (Qnil); else return (rb_str_new2(xmlTreeIndentString)); } /* * call-seq: * XML.default_tree_indent_string = "string" * * Set the default string used by parsers to indent the XML tree * for output. */ static VALUE rxml_default_tree_indent_string_set(VALUE klass, VALUE string) { Check_Type(string, T_STRING); xmlTreeIndentString = (const char *)xmlStrdup((xmlChar *)StringValuePtr(string)); return (string); } /* * call-seq: * XML.default_validity_checking -> (true|false) * * Determine whether parsers perform XML validation by default. */ static VALUE rxml_default_validity_checking_get(VALUE klass) { if (xmlDoValidityCheckingDefaultValue) return (Qtrue); else return (Qfalse); } /* * call-seq: * XML.default_validity_checking = true|false * * Controls whether parsers perform XML validation by default. */ static VALUE rxml_default_validity_checking_set(VALUE klass, VALUE value) { if (value == Qfalse) { xmlDoValidityCheckingDefaultValue = 0; return (Qfalse); } else { xmlDoValidityCheckingDefaultValue = 1; return (Qtrue); } } /* * call-seq: * XML.default_warnings -> (true|false) * * Determine whether parsers output warnings by default. */ static VALUE rxml_default_warnings_get(VALUE klass) { if (xmlGetWarningsDefaultValue) return (Qtrue); else return (Qfalse); } /* * call-seq: * XML.default_warnings = true|false * * Controls whether parsers output warnings by default. */ static VALUE rxml_default_warnings_set(VALUE klass, VALUE value) { if (value == Qfalse) { xmlGetWarningsDefaultValue = 0; return (Qfalse); } else { xmlGetWarningsDefaultValue = 1; return (Qtrue); } } /* * call-seq: * XML.default_compression -> (true|false) * * Determine whether parsers use Zlib compression by default * (requires libxml to be compiled with Zlib support). */ static VALUE rxml_default_compression_get(VALUE klass) { #ifdef HAVE_ZLIB_H return(INT2FIX(xmlGetCompressMode())); #else rb_warn("libxml was compiled without zlib support"); return (Qfalse); #endif } /* * call-seq: * XML.default_compression = true|false * * Controls whether parsers use Zlib compression by default * (requires libxml to be compiled with Zlib support). */ static VALUE rxml_default_compression_set(VALUE klass, VALUE num) { #ifdef HAVE_ZLIB_H Check_Type(num, T_FIXNUM); xmlSetCompressMode(FIX2INT(num)); return(num); #else rb_warn("libxml was compiled without zlib support"); return (Qfalse); #endif } /* * call-seq: * XML.default_save_no_empty_tags -> (true|false) * * Determine whether serializer outputs empty tags by default. */ static VALUE rxml_default_save_no_empty_tags_get(VALUE klass) { if (xmlSaveNoEmptyTags) return (Qtrue); else return (Qfalse); } /* * call-seq: * XML.default_save_no_empty_tags = true|false * * Controls whether serializer outputs empty tags by default. */ static VALUE rxml_default_save_no_empty_tags_set(VALUE klass, VALUE value) { if (value == Qfalse) { xmlSaveNoEmptyTags = 0; return (Qfalse); } else if (value == Qtrue) { xmlSaveNoEmptyTags = 1; return (Qtrue); } else { rb_raise(rb_eArgError, "Invalid argument, must be a boolean"); } } /* * call-seq: * XML.features -> ["feature", ..., "feature"] * * Obtains an array of strings representing features supported * (and enabled) by the installed libxml. */ static VALUE rxml_features(VALUE klass) { VALUE arr, str; int i, len = MAX_LIBXML_FEATURES_LEN; char **list = NULL; list = ALLOC_N(char *,MAX_LIBXML_FEATURES_LEN); MEMZERO(list, char *, MAX_LIBXML_FEATURES_LEN); arr = rb_ary_new(); if (xmlGetFeaturesList(&len, (const char **) list) == -1) return Qnil; for (i = 0; i < len; i++) { str = rb_str_new2((const char *) list[i]); rb_gc_unregister_address(&str); rb_ary_push(arr, str); } if (len == MAX_LIBXML_FEATURES_LEN) rb_warn( "Please contact libxml-devel@rubyforge.org and ask to have the \"MAX_LIBXML_FEATURES_LEN increased\" because you could possibly be seeing an incomplete list"); ruby_xfree(list); return (arr); } /* * call-seq: * XML.indent_tree_output -> (true|false) * * Determines whether XML output will be indented * (using the string supplied to +default_indent_tree_string+) */ static VALUE rxml_indent_tree_output_get(VALUE klass) { if (xmlIndentTreeOutput) return (Qtrue); else return (Qfalse); } /* * call-seq: * XML.indent_tree_output = true|false * * Controls whether XML output will be indented * (using the string supplied to +default_indent_tree_string+) */ static VALUE rxml_indent_tree_output_set(VALUE klass, VALUE value) { if (value == Qtrue) { xmlIndentTreeOutput = 1; return (Qtrue); } else if (value == Qfalse) { xmlIndentTreeOutput = 0; return (Qfalse); } else { rb_raise(rb_eArgError, "Invalid argument, must be boolean"); } } /* * call-seq: * XML.memory_dump -> (true|false) * * Perform a parser memory dump (requires memory debugging * support in libxml). */ static VALUE rxml_memory_dump(VALUE self) { #ifdef DEBUG_MEMORY_LOCATION xmlMemoryDump(); return(Qtrue); #else rb_warn("libxml was compiled without memory debugging support"); return (Qfalse); #endif } /* * call-seq: * XML.memory_used -> num_bytes * * Perform a parser memory dump (requires memory debugging * support in libxml). */ static VALUE rxml_memory_used(VALUE self) { #ifdef DEBUG_MEMORY_LOCATION return(INT2NUM(xmlMemUsed())); #else rb_warn("libxml was compiled without memory debugging support"); return (Qfalse); #endif } /* The libxml gem provides Ruby language bindings for GNOME's Libxml2 * XML toolkit. Refer to the README file to get started * and the LICENSE file for copyright and distribution information. */ void rxml_init_xml(void) { mXML = rb_define_module_under(mLibXML, "XML"); /* Constants */ rb_define_const(mXML, "LIBXML_VERSION", rb_str_new2(LIBXML_DOTTED_VERSION)); rb_define_const(mXML, "VERSION", rb_str_new2(RUBY_LIBXML_VERSION)); rb_define_const(mXML, "VERNUM", INT2NUM(RUBY_LIBXML_VERNUM)); rb_define_const(mXML, "XML_NAMESPACE", rb_str_new2((const char*) XML_XML_NAMESPACE)); rb_define_module_function(mXML, "enabled_automata?", rxml_enabled_automata_q, 0); rb_define_module_function(mXML, "enabled_c14n?", rxml_enabled_c14n_q, 0); rb_define_module_function(mXML, "enabled_catalog?", rxml_enabled_catalog_q, 0); rb_define_module_function(mXML, "enabled_debug?", rxml_enabled_debug_q, 0); rb_define_module_function(mXML, "enabled_docbook?", rxml_enabled_docbook_q, 0); rb_define_module_function(mXML, "enabled_ftp?", rxml_enabled_ftp_q, 0); rb_define_module_function(mXML, "enabled_http?", rxml_enabled_http_q, 0); rb_define_module_function(mXML, "enabled_html?", rxml_enabled_html_q, 0); rb_define_module_function(mXML, "enabled_iconv?", rxml_enabled_iconv_q, 0); rb_define_module_function(mXML, "enabled_memory_debug?", rxml_enabled_memory_debug_location_q, 0); rb_define_module_function(mXML, "enabled_regexp?", rxml_enabled_regexp_q, 0); rb_define_module_function(mXML, "enabled_schemas?", rxml_enabled_schemas_q, 0); rb_define_module_function(mXML, "enabled_thread?", rxml_enabled_thread_q, 0); rb_define_module_function(mXML, "enabled_unicode?", rxml_enabled_unicode_q, 0); rb_define_module_function(mXML, "enabled_xinclude?", rxml_enabled_xinclude_q, 0); rb_define_module_function(mXML, "enabled_xpath?", rxml_enabled_xpath_q, 0); rb_define_module_function(mXML, "enabled_xpointer?", rxml_enabled_xpointer_q, 0); rb_define_module_function(mXML, "enabled_zlib?", rxml_enabled_zlib_q, 0); rb_define_module_function(mXML, "catalog_dump", rxml_catalog_dump, 0); rb_define_module_function(mXML, "catalog_remove", rxml_catalog_remove, 1); rb_define_module_function(mXML, "check_lib_versions", rxml_check_lib_versions, 0); rb_define_module_function(mXML, "debug_entities", rxml_debug_entities_get, 0); rb_define_module_function(mXML, "debug_entities=", rxml_debug_entities_set, 1); rb_define_module_function(mXML, "default_compression", rxml_default_compression_get, 0); rb_define_module_function(mXML, "default_compression=", rxml_default_compression_set, 1); rb_define_module_function(mXML, "default_keep_blanks", rxml_default_keep_blanks_get, 0); rb_define_module_function(mXML, "default_keep_blanks=", rxml_default_keep_blanks_set, 1); rb_define_module_function(mXML, "default_load_external_dtd", rxml_default_load_external_dtd_get, 0); rb_define_module_function(mXML, "default_load_external_dtd=", rxml_default_load_external_dtd_set, 1); rb_define_module_function(mXML, "default_line_numbers", rxml_default_line_numbers_get, 0); rb_define_module_function(mXML, "default_line_numbers=", rxml_default_line_numbers_set, 1); rb_define_module_function(mXML, "default_options", rxml_default_options_get, 0); rb_define_module_function(mXML, "default_pedantic_parser", rxml_default_pedantic_parser_get, 0); rb_define_module_function(mXML, "default_pedantic_parser=", rxml_default_pedantic_parser_set, 1); rb_define_module_function(mXML, "default_substitute_entities", rxml_default_substitute_entities_get, 0); rb_define_module_function(mXML, "default_substitute_entities=", rxml_default_substitute_entities_set, 1); rb_define_module_function(mXML, "default_tree_indent_string", rxml_default_tree_indent_string_get, 0); rb_define_module_function(mXML, "default_tree_indent_string=", rxml_default_tree_indent_string_set, 1); rb_define_module_function(mXML, "default_validity_checking", rxml_default_validity_checking_get, 0); rb_define_module_function(mXML, "default_validity_checking=", rxml_default_validity_checking_set, 1); rb_define_module_function(mXML, "default_warnings", rxml_default_warnings_get, 0); rb_define_module_function(mXML, "default_warnings=", rxml_default_warnings_set, 1); rb_define_module_function(mXML, "default_save_no_empty_tags", rxml_default_save_no_empty_tags_get, 0); rb_define_module_function(mXML, "default_save_no_empty_tags=", rxml_default_save_no_empty_tags_set, 1); rb_define_module_function(mXML, "features", rxml_features, 0); rb_define_module_function(mXML, "indent_tree_output", rxml_indent_tree_output_get, 0); rb_define_module_function(mXML, "indent_tree_output=", rxml_indent_tree_output_set, 1); rb_define_module_function(mXML, "memory_dump", rxml_memory_dump, 0); rb_define_module_function(mXML, "memory_used", rxml_memory_used, 0); } libxml-ruby-3.2.1/ext/libxml/ruby_xml_xinclude.h0000644000004100000410000000036113760147770022023 0ustar www-datawww-data/* Please see the LICENSE file for copyright and distribution information */ #ifndef __RXML_XINCLUDE__ #define __RXML_XINCLUDE__ extern VALUE cXMLXInclude; extern VALUE eXMLXIncludeError; void rxml_init_xinclude(void); #endif libxml-ruby-3.2.1/libxml-ruby.gemspec0000644000004100000410000000367113760147770017651 0ustar www-datawww-data# encoding: utf-8 require 'date' # Determine the current version of the software version = File.read('ext/libxml/ruby_xml_version.h').match(/\s*RUBY_LIBXML_VERSION\s*['"](\d.+)['"]/)[1] Gem::Specification.new do |spec| spec.name = 'libxml-ruby' spec.version = version spec.homepage = 'http://xml4r.github.com/libxml-ruby' spec.summary = 'Ruby Bindings for LibXML2' spec.description = <<-EOS The Libxml-Ruby project provides Ruby language bindings for the GNOME Libxml2 XML toolkit. It is free software, released under the MIT License. Libxml-ruby's primary advantage over REXML is performance - if speed is your need, these are good libraries to consider, as demonstrated by the informal benchmark below. EOS spec.authors = ['Ross Bamform', 'Wai-Sun Chia', 'Sean Chittenden', 'Dan Janwoski', 'Anurag Priyam', 'Charlie Savage', 'Ryan Johnson'] spec.platform = Gem::Platform::RUBY spec.bindir = 'bin' spec.extensions = ['ext/libxml/extconf.rb'] spec.files = Dir.glob(['HISTORY', 'LICENSE', 'libxml-ruby.gemspec', 'MANIFEST', 'Rakefile', 'README.rdoc', 'setup.rb', 'ext/libxml/*.def', 'ext/libxml/*.h', 'ext/libxml/*.c', 'ext/libxml/*.rb', 'ext/vc/*.sln', 'ext/vc/*.vcprojx', 'lib/**/*.rb', 'script/**/*', 'test/**/*']) spec.test_files = Dir.glob('test/test_*.rb') spec.required_ruby_version = '>= 2.5' spec.date = DateTime.now spec.add_development_dependency('rake-compiler') spec.add_development_dependency('minitest') spec.license = 'MIT' end