Class: RDFObject::XMLParser

Inherits:
Parser
  • Object
show all
Defined in:
lib/rdf_objects/parsers.rb

Instance Attribute Summary

Attributes inherited from Parser

#collection

Instance Method Summary collapse

Methods inherited from Parser

init_parser, parse, #sanitize_uri

Constructor Details

#initialize(data = nil) ⇒ XMLParser

Returns a new instance of XMLParser.



289
290
291
292
293
294
295
296
297
# File 'lib/rdf_objects/parsers.rb', line 289

def initialize(data=nil)
  super(data)
  @uris = []
  @tags = {}
  @parser = Nokogiri::XML::SAX::Parser.new(self)
  @hierarchy = []
  @xml_base = nil
  @default_namespace = nil
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(methName, *args) ⇒ Object



313
314
315
316
317
318
319
# File 'lib/rdf_objects/parsers.rb', line 313

def method_missing(methName, *args)
  sax_methods = [:xmldecl, :start_document, :end_document, :start_element,
    :end_element, :comment, :warning, :error, :cdata_block]
  unless sax_methods.index(methName)
    raise NoMethodError.new("undefined method '#{methName} for #{self}", 'no_meth')
  end
end

Instance Method Details

#add_layer(name, attributes, prefix, uri, ns) ⇒ Object



348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
# File 'lib/rdf_objects/parsers.rb', line 348

def add_layer name, attributes, prefix, uri, ns
  layer = {:name=>"#{uri}#{name}"}
  if attributes['http://www.w3.org/1999/02/22-rdf-syntax-ns#about'] or 
    (attributes['http://www.w3.org/1999/02/22-rdf-syntax-ns#nodeID'] && (@hierarchy.length == 1 || @hierarchy.last[:predicate]))
    id = attributes['http://www.w3.org/1999/02/22-rdf-syntax-ns#about'] || 
      attributes['http://www.w3.org/1999/02/22-rdf-syntax-ns#nodeID']
    id = sanitize_uri(id) if attributes['http://www.w3.org/1999/02/22-rdf-syntax-ns#about']
    layer[:resource] = @collection.find_or_create(id)
    unless "#{uri}#{name}" == "http://www.w3.org/1999/02/22-rdf-syntax-ns#Description"
      layer[:resource].relate("http://www.w3.org/1999/02/22-rdf-syntax-ns#type", @collection.find_or_create("#{uri}#{name}"))
    end 
    if !@hierarchy.empty? && @hierarchy.last[:predicate]
      self.current_resource.relate(self.current_predicate, layer[:resource])
    end
  elsif attributes["http://www.w3.org/1999/02/22-rdf-syntax-ns#resource"] or attributes["http://purl.org/rss/1.0/resource"] or 
      (attributes['http://www.w3.org/1999/02/22-rdf-syntax-ns#nodeID'] && @hierarchy.length > 1 && @hierarchy.last[:predicate].nil?)
    res = attributes['http://www.w3.org/1999/02/22-rdf-syntax-ns#resource'] || attributes["http://purl.org/rss/1.0/resource"] || attributes['http://www.w3.org/1999/02/22-rdf-syntax-ns#nodeID']
    self.current_resource.assert("#{uri}#{name}", @collection.find_or_create(sanitize_uri(res)))    
    layer[:predicate] = layer[:name]
  else
    unless layer[:name] == "http://www.w3.org/1999/02/22-rdf-syntax-ns#RDF"
      layer[:predicate] = layer[:name]
    end
  end
  if attributes["http://www.w3.org/1999/02/22-rdf-syntax-ns#datatype"] || attributes["http://www.w3.org/XML/1998/namespace/lang"]
    layer[:datatype] = attributes["http://www.w3.org/1999/02/22-rdf-syntax-ns#datatype"] if attributes["http://www.w3.org/1999/02/22-rdf-syntax-ns#datatype"]
    layer[:language] = attributes["http://www.w3.org/XML/1998/namespace/lang"].to_sym if attributes["http://www.w3.org/XML/1998/namespace/lang"]        
  end    
  layer[:base_uri] = Addressable::URI.parse(attributes["http://www.w3.org/XML/1998/namespace/base"]).normalize if attributes["http://www.w3.org/XML/1998/namespace/base"]  
  @hierarchy << layer
  attributes_as_assertions(attributes)
end

#assert_literal(layer) ⇒ Object



389
390
391
392
# File 'lib/rdf_objects/parsers.rb', line 389

def assert_literal(layer)
  lit = RDF::Literal.new(layer[:literal], {:datatype=>layer[:datatype], :language=>layer[:language]})  
  self.current_resource.assert(layer[:predicate], lit) if layer[:predicate]     
end

#attributes_as_assertions(attributes) ⇒ Object



333
334
335
336
337
338
339
340
341
342
343
344
345
346
# File 'lib/rdf_objects/parsers.rb', line 333

def attributes_as_assertions(attributes)
  skip = ["http://www.w3.org/XML/1998/namespace/lang", "http://www.w3.org/XML/1998/namespace/base", 
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#resource", "http://www.w3.org/1999/02/22-rdf-syntax-ns#about",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#nodeID", "http://www.w3.org/1999/02/22-rdf-syntax-ns#datatype",
    "http://purl.org/rss/1.0/resource"]
  attributes.each_pair do | uri, value |
    next if skip.index(uri)
    lit = RDF::Literal.new(value, {:datatype=>attributes["http://www.w3.org/1999/02/22-rdf-syntax-ns#datatype"]})
    if attributes["http://www.w3.org/XML/1998/namespace/lang"]
      lit.language = attributes["http://www.w3.org/XML/1998/namespace/lang"].to_sym
    end
    self.current_resource.assert(uri, lit)
  end
end

#attributes_to_hash(attributes, namespaces, name, prefix) ⇒ Object



321
322
323
324
325
326
327
328
329
330
331
# File 'lib/rdf_objects/parsers.rb', line 321

def attributes_to_hash(attributes, namespaces, name, prefix)
  hash = {}
  attributes.each do | att |
    ns = att.uri || @default_namespace
    unless ns =~ /[#\/]$/
      ns << "/"
    end
    hash["#{ns}#{att.localname}"] = att.value
  end
  hash
end

#base_uriObject



416
417
418
419
420
421
# File 'lib/rdf_objects/parsers.rb', line 416

def base_uri
  @hierarchy.reverse.each do | layer |
    return layer[:base_uri] if layer[:base_uri]
  end      
  @base_uri
end

#characters(text) ⇒ Object



439
440
441
442
443
# File 'lib/rdf_objects/parsers.rb', line 439

def characters text
  if self.current_literal && !text.strip.empty?
    self.current_literal << text.strip
  end
end

#check_for_default_ns(ns) ⇒ Object



430
431
432
433
434
435
436
437
# File 'lib/rdf_objects/parsers.rb', line 430

def check_for_default_ns(ns)
  return unless self.current_resource.empty?
  ns.each do | n |
    if n.first.nil?
      @default_namespace = n.last
    end
  end
end

#current_literalObject



406
407
408
409
410
411
412
413
414
# File 'lib/rdf_objects/parsers.rb', line 406

def current_literal
  unless @hierarchy.empty?
    return @hierarchy.last[:literal] if @hierarchy.last[:literal]
    unless @hierarchy.last[:resource]
      @hierarchy.last[:literal] = ""
      return @hierarchy.last[:literal]
    end
  end
end

#current_predicateObject



400
401
402
403
404
# File 'lib/rdf_objects/parsers.rb', line 400

def current_predicate
  @hierarchy.reverse.each do | layer |
    return layer[:predicate] if layer[:predicate]
  end      
end

#current_resourceObject



394
395
396
397
398
# File 'lib/rdf_objects/parsers.rb', line 394

def current_resource
  @hierarchy.reverse.each do | layer |
    return layer[:resource] if layer[:resource]
  end
end

#data=(xml) ⇒ Object



299
300
301
302
303
304
305
306
# File 'lib/rdf_objects/parsers.rb', line 299

def data=(xml)
  if xml.is_a?(String)
    @rdfxml = xml
  elsif xml.respond_to?(:read)
    xml.rewind
    @rdfxml = xml.read
  end
end

#end_element_namespace(name, prefix = nil, uri = nil) ⇒ Object



445
446
447
# File 'lib/rdf_objects/parsers.rb', line 445

def end_element_namespace name, prefix = nil, uri = nil
  remove_layer("#{uri}#{name}")
end

#parseObject



308
309
310
311
# File 'lib/rdf_objects/parsers.rb', line 308

def parse
  @parser.parse(@rdfxml)
  @collection
end

#remove_layer(name) ⇒ Object



381
382
383
384
385
386
387
# File 'lib/rdf_objects/parsers.rb', line 381

def remove_layer(name)
  unless @hierarchy.last[:name] == name
    throw ArgumentError, "Hierarchy out of sync."
  end
  layer = @hierarchy.pop
  assert_literal(layer) if layer[:literal] && !layer[:literal].empty?
end

#start_element_namespace(name, attributes = [], prefix = nil, uri = nil, ns = {}) ⇒ Object



423
424
425
426
427
428
# File 'lib/rdf_objects/parsers.rb', line 423

def start_element_namespace name, attributes = [], prefix = nil, uri = nil, ns = {}
  check_for_default_ns(ns)
  attributes = attributes_to_hash(attributes, ns, name, prefix)
  
  add_layer(name, attributes, prefix, uri, ns)
end