public
Description: ruby libxml library targetting speed and ease of use. provides an hpricot-like interface to xml
Homepage: http://trac.hasno.info/fastxml
Clone URL: git://github.com/segfault/fastxml.git
fastxml / ext / fastxml_attrlist.c
100644 134 lines (109 sloc) 3.634 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
* Document-class: FastXml::AttrList
*
* call-seq:
* doc = FastXml( docfile ) # from FastXml::Doc
* n = doc.root # pull the root node
* attrlist = n.attr # pull the FastXml::AttrList for the node
* puts attrlist[:some_attr]
* puts attrlist["some_attr"]
*/
// Please see the LICENSE file for copyright, licensing and distribution information
 
#include "fastxml.h"
#include "fastxml_node.h"
#include "fastxml_doc.h"
#include "fastxml_nodelist.h"
#include "fastxml_attrlist.h"
 
/* {{{ fastml_attr_list
*/
void Init_fastxml_attrlist()
{
  #ifdef RDOC_SHOULD_BE_SMARTER__THIS_IS_NEVER_RUN
    rb_mFastXml = rb_define_module( "FastXml" );
  #endif
  rb_cFastXmlAttrList = rb_define_class_under( rb_mFastXml, "AttrList", rb_cObject );    
    
  rb_include_module( rb_cFastXmlAttrList, rb_mEnumerable );
  rb_define_method( rb_cFastXmlAttrList, "initialize", fastxml_attrlist_initialize, 0 );
  rb_define_method( rb_cFastXmlAttrList, "[]", fastxml_attrlist_indexer, 1 );
  rb_define_method( rb_cFastXmlAttrList, "[]=", fastxml_attrlist_indexer_set, 2 );
  rb_define_method( rb_cFastXmlAttrList, "include?", fastxml_attrlist_include, 1 );  
}
 
VALUE fastxml_attrlist_initialize(VALUE self)
{
    return self;
}
 
/* Returns the value of the attribute with the provided attr_name
* as a string.
* nil if the attribute does not exist.
*
* call-seq:
* puts node.attr[:an_attr_name]
*/
VALUE fastxml_attrlist_indexer(VALUE self, VALUE attr_name)
{
  VALUE ret, dv, attr_raw_str;
  fxml_data_t *data;
  xmlChar *raw_ret, *name_str;
  
  if (attr_name == Qnil)
    return Qnil;  
  
  dv = rb_iv_get( self, "@lxml_doc" );
  Data_Get_Struct( dv, fxml_data_t, data );
  
  attr_raw_str = rb_funcall( attr_name, s_to_s, 0 );
  name_str = (xmlChar*)StringValuePtr( attr_raw_str );
  raw_ret = xmlGetProp( data->node, name_str );
  if (raw_ret == NULL)
    return Qnil;
    
  ret = rb_str_new2( (const char*)raw_ret );
  xmlFree( raw_ret );
  
  return ret;
}
 
/* Assignes a value to the attribute with the provided attr_name.
* if the value provided is nil, the attribute is removed from the element.
*
* call-seq:
* node.attr[:an_attr_name] = "testing" # adds the attribute if it doesn't exist
* node.attr[:an_attr_name] = nil # removes the attribute if it exists
*/
VALUE fastxml_attrlist_indexer_set(VALUE self, VALUE attr_name, VALUE attr_value)
{
  VALUE dv, attr_raw_str;
  fxml_data_t *data;
  xmlChar *val, *name_str;
  
  if (attr_name == Qnil)
    return Qnil;  
  
  dv = rb_iv_get( self, "@lxml_doc" );
  Data_Get_Struct( dv, fxml_data_t, data );
  
  attr_raw_str = rb_funcall( attr_name, s_to_s, 0 );
  name_str = (xmlChar*)StringValuePtr( attr_raw_str );
 
  if (attr_value == Qnil) {
    xmlUnsetProp( data->node, name_str ); // don't care if the node doesn't exist, as the end result is the same.
  } else {
    val = (xmlChar*)StringValuePtr( attr_value );
 
      xmlSetProp( data->node, name_str, val );
  }
 
 
  return attr_value;
}
 
/* Returns True if the FastXml::AttrList contains an attribute
* with the specified attr_name. Returns nil otherwise.
*
* call-seq:
* puts "FAIL" unless node.attr.include?(:a_required_node)
*/
VALUE fastxml_attrlist_include(VALUE self, VALUE attr_name)
{
  VALUE dv, attr_raw_str;
  fxml_data_t *data;
  xmlChar *raw_ret, *name_str;
  
  if (attr_name == Qnil)
    return Qnil;
  
  dv = rb_iv_get( self, "@lxml_doc" );
  Data_Get_Struct( dv, fxml_data_t, data );
  
  attr_raw_str = rb_funcall( attr_name, s_to_s, 0 );
  name_str = (xmlChar*)StringValuePtr( attr_raw_str );
  raw_ret = xmlGetProp( data->node, name_str );
  if (raw_ret == NULL)
    return Qnil;  
  
  return Qtrue;
}
 
 
/* }}} fastxml_attr_list
*/