VALUE rxml_xpath_object_wrap(xmlDocPtr xdoc, xmlXPathObjectPtr xpop) { int i; rxml_xpath_object *rxpop = ALLOC(rxml_xpath_object); rxpop->xdoc =xdoc; rxpop->xpop = xpop; rxpop->nsnodes = rb_ary_new(); /* 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(rxpop->nsnodes, ns); } } } return Data_Wrap_Struct(cXMLXPathObject, rxml_xpath_object_mark, rxml_xpath_object_free, rxpop); }
/* * call-seq: * ns.next -> XML::Namespace * * Obtain the next namespace. * * Usage: * * doc = XML::Document.string('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"/>') * 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, NULL)); }
/* * 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, NULL); }
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]); } }