/* * wsman-xml.i * * xml structure accessors for openwsman swig bindings * */ /* * Document-class: XmlNs * Xml namespace * */ %rename(XmlNs) __WsXmlNs; %nodefault __WsXmlNs; /* part of WsXmlAttr */ struct __WsXmlNs {}; /* without empty struct, the %rename isn't executed. */ typedef struct __WsXmlNs* WsXmlNsH; /* * XmlDoc * * Implementation advice * * DONT do a %newobject on functions returning WsXmlDoc. Swig will * free the WsXmlDocH immediately after wrapping ! * */ %rename(XmlDoc) _WsXmlDoc; %nodefault _WsXmlDoc; struct _WsXmlDoc {}; typedef struct _WsXmlDoc* WsXmlDocH; /* * Document-class: XmlDoc * * XmlDoc holds an XML document and thus represents the root of an XML * tree. XmlDoc is optimized for SOAP type documents, giving accessors * to the SOAP envelope, header and body. * * Instances of the other XML related classes like XmlAttr and XmlNode * can only be created with an associated XmlDoc instance. * * Main properties of the XML document are * * name of the root element * * encoding (defaults to _UTF-8_) * */ %extend _WsXmlDoc { /* * Create XmlDoc with node name * optionally pass namespace as 2nd arg (defaults to NULL) * */ _WsXmlDoc(const char *name, const char *ns = NULL) { return ws_xml_create_doc(ns, name); } /* destructor */ ~_WsXmlDoc() { ws_xml_destroy_doc( $self ); } %typemap(newfree) char * "free($1);"; #if defined(SWIGRUBY) %alias string "to_xml"; #endif #if defined(SWIGPYTHON) %rename("__str__") string(); #endif #if defined(SWIGJAVA) %rename("toString") string(); #endif %newobject string; /* * generic (indented) string representation of the XmlDoc UTF-8 encoded. * see encode for setting the encoding. * * alias: to_xml * * call-seq: * doc.string -> String * doc.to_xml -> String * */ char *string() { int size; char *buf; /* force utf-8 encoding since e.g. winrm sends utf-16 */ ws_xml_dump_memory_node_tree_enc( ws_xml_get_doc_root($self), &buf, &size, "UTF-8" ); return buf; } #if defined(SWIGRUBY) %alias encode "to_s"; #endif %newobject encode; /* * encode document as string with specific encoding * (non-indented representation) * * encoding defaults to 'utf-8' * * alias: to_s * * call-seq: * doc.encode -> String * doc.encode("UTF-16") -> String * doc.to_s -> string * */ char *encode(const char *encoding = "utf-8") { int size; char *buf; ws_xml_dump_memory_enc( $self, &buf, &size, encoding ); return buf; } /* * dump document to file * * call-seq: * doc.dump(IO) -> nil * */ void dump_file(FILE *fp) { ws_xml_dump_doc( fp, $self ); } /* * get root node of doc * call-seq: * doc.root -> XmlNode * */ WsXmlNodeH root() { return ws_xml_get_doc_root( $self ); } /* * get soap envelope node * call-seq: * doc.envelope -> XmlNode * */ WsXmlNodeH envelope() { return ws_xml_get_soap_envelope( $self ); } /* * get soap header node * call-seq: * doc.header -> XmlNode * */ WsXmlNodeH header() { return ws_xml_get_soap_header( $self ); } /* * get soap body node * call-seq: * doc.body -> XmlNode * */ WsXmlNodeH body() { return ws_xml_get_soap_body( $self ); } /* * get soap element node by name * returns nil if no element with the name can be found * * call-seq: * doc.element(String) -> XmlNode * */ WsXmlNodeH element(const char *name) { return ws_xml_get_soap_element( $self, name ); } %newobject context; /* * get enumeration context as string * return nil if context not present or empty * * call-seq: * doc.context -> String * */ const char *context() { char *c = wsmc_get_enum_context( $self ); if (c) { if (*c) return c; u_free(c); } return NULL; } /* * Generate fault document based on given status * * This creates a new XmlDoc instance representing a fault * * call-seq: * doc.generate_fault(Openwsman::Status) -> XmlDoc * */ WsXmlDocH generate_fault(WsmanStatus *s) { return wsman_generate_fault( $self, s->fault_code, s->fault_detail_code, s->fault_msg); } #if defined(SWIGRUBY) %rename("fault?") is_fault(); %typemap(out) int is_fault "$result = ($1 != 0) ? Qtrue : Qfalse;"; #endif #if defined(SWIGJAVA) %rename("isFault") is_fault(); %typemap(jstype) int is_fault "boolean" %typemap(javaout) int is_fault { return ( $jnicall != 0 ) ? true : false; } #endif /* * Check if document represents a fault * * call-seq: * doc.fault?(XmlDoc) -> Boolean * */ int is_fault() { return wsmc_check_for_fault( $self ); } %newobject fault; /* * retrieve fault data * * call-seq: * doc.fault(XmlDoc) -> Openwsman::Fault * doc.fault(XmlDoc) -> nil # if XmlDoc is not a fault * */ WsManFault *fault() { WsManFault *f = NULL; if (wsmc_check_for_fault($self)) { f = (WsManFault *)calloc(1, sizeof(WsManFault)); wsmc_get_fault_data($self, f); } return f; } /* * Generate response envelope document, optionally relating to a * specific action. * * This creates a new XmlDoc instance representing a response. * * call-seq: * doc.create_response_envelope(String action) -> XmlDoc * */ WsXmlDocH create_response_envelope(const char *action = NULL) { return wsman_create_response_envelope($self, action); } #if defined(SWIGRUBY) %rename("end_of_sequence?") is_end_of_sequence(); %typemap(out) int is_end_of_sequence "$result = ($1 != 0) ? Qtrue : Qfalse;"; #endif /* * Check if document represents an end of sequence (last enumeration item) * * call-seq: * doc.is_end_of_sequence() -> Boolean * */ int is_end_of_sequence() { return NULL != ws_xml_find_in_tree( ws_xml_get_soap_body( $self ), XML_NS_ENUMERATION, WSENUM_END_OF_SEQUENCE, 1 ); } } /* * Document-class: XmlNode * * XmlNode is a node inside the XML document tree. * * A node has * * a name * * a namespace (optional) * * attributes * * text (optional) * * a parent * * a document (root) * * children (empty for tail nodes) * */ %rename(XmlNode) __WsXmlNode; %nodefault __WsXmlNode; struct __WsXmlNode {}; /* without empty struct, the %rename isn't executed. */ typedef struct __WsXmlNode* WsXmlNodeH; %extend __WsXmlNode { ~__WsXmlNode() { ws_xml_unlink_node($self); } #if defined(SWIGRUBY) %alias text "to_s"; %alias string "to_xml"; #endif #if defined(SWIGPYTHON) %rename("__str__") text(); #endif #if defined(SWIGJAVA) %rename("toString") text(); %rename("toXML") string(); #endif %newobject string; /* * dump node as XML string * * alias: to_xml * * call-seq: * node.string(XmlNode) -> String * */ char *string() { int size; char *buf; ws_xml_dump_memory_node_tree( $self, &buf, &size ); return buf; } /* * dump node to file * * call-seq: * node.dump_file(IO) -> nil * */ void dump_file(FILE *fp) { ws_xml_dump_node_tree( fp, $self ); } #if defined(SWIGRUBY) %alias equal "=="; %typemap(out) int equal "$result = ($1 != 0) ? Qtrue : Qfalse;"; #endif #if defined(SWIGPERL) int __eq__( WsXmlNodeH n ) #else int equal( WsXmlNodeH n ) #endif /* * Test for identity (same object) * * call-seq: * XmlNode == XmlNode -> Boolean * */ { return $self == n; } /* * get text (without xml tags) of node * * alias: to_s * * call-seq: * node.text() -> String * */ char *text() { return ws_xml_get_node_text( $self ); } #if defined(SWIGRUBY) %rename( "text=" ) set_text( const char *text ); #endif /* * Set text of node * * call-seq: * node.text = String * */ void set_text( const char *text ) { ws_xml_set_node_text( $self, text ); } /* * get XmlDoc to which node belongs * * call-seq: * node.doc -> XmlDoc * */ WsXmlDocH doc() { return ws_xml_get_node_doc( $self ); } /* * get parent for node * * call-seq: * node.parent -> XmlNode * */ WsXmlNodeH parent() { return ws_xml_get_node_parent( $self ); } #if defined(SWIGRUBY) %alias child "first"; #endif /* * get first child of node * * call-seq: * node.child -> XmlNode * */ WsXmlNodeH child() { return xml_parser_get_first_child($self); } /* * get name for node * * call-seq: * node.name -> String * */ char *name() { return ws_xml_get_node_local_name( $self ); } #if defined(SWIGRUBY) %rename("name=") set_name( const char *name); #endif /* * set name of node * * call-seq: * node.name = String * */ void set_name( const char *name ) { ws_xml_set_node_name( $self, ws_xml_get_node_name_ns( $self ), name ); } /* * get namespace for node * * call-seq: * node.ns -> String * */ char *ns() { return ws_xml_get_node_name_ns( $self ); } #if defined(SWIGRUBY) %rename("ns=") set_ns( const char *nsuri ); #endif /* * set namespace of node * * call-seq: * node.ns = String * */ void set_ns( const char *ns ) { ws_xml_set_ns( $self, ns, ws_xml_get_node_name_ns_prefix($self) ); } /* * get prefix of nodes namespace * * call-seq: * node.prefix -> String * */ const char *prefix() { return ws_xml_get_node_name_ns_prefix($self); } #if defined(SWIGRUBY) %rename("lang=") set_lang(const char *lang); #endif /* * set language * * call-seq: * node.lang = String * */ void set_lang(const char *lang) { ws_xml_set_node_lang($self, lang); } /* * find node within tree * a NULL passed as 'ns' (namespace) is treated as wildcard * * call-seq: * node.find("namespace", "name") -> XmlNode # recursive * node.find("namespace", "name", 0) -> XmlNode # non-recursive * */ WsXmlNodeH find( const char *ns, const char *name, int recursive = 1) { return ws_xml_find_in_tree( $self, ns, name, recursive ); } /* * iterate over siblings * * finds next sibling with same namespace and name * * See also XmlNode#each * * XmlNode#each iterates over children, XmlNode#next over siblings * * Example: * * ... * ... * ... * ... * ... * ... * * * node = root.Foo # points to node * * bar = node.Bar * while bar do * bar = bar.next * end * * will give you four iterations (all nodes) * * child = node.Bar * while child do * child = child.next(1) * end * * will give you six iterations (all children of ) * The latter example is equal to * * node.each do |child| * ... * end * */ WsXmlNodeH next(int all = 0) { WsXmlNodeH next_node = xml_parser_get_next_child($self); if (next_node && !all) { const char *ns_uri = ws_xml_get_node_name_ns($self); const char *name = ws_xml_get_node_local_name($self); if (ws_xml_is_node_qname(next_node, ns_uri, name) == 0) { next_node = NULL; } } return next_node; } /* * count node children * if name given, count children with this name * if name + ns given, count children with this namespace and name * */ int size(const char *name = NULL, const char *ns = NULL) { return ws_xml_get_child_count_by_qname($self, ns, name); } /* * add child (namespace, name, text) to node * */ WsXmlNodeH add( const char *ns, const char *name, const char *text = NULL ) { return ws_xml_add_child( $self, ns, name, text ); } /* * add child (namespace, name, text) before(!) node * */ WsXmlNodeH add_before( const char *ns, const char *name, const char *text = NULL ) { return ws_xml_add_prev_sibling( $self, ns, name, text ); } #if defined(SWIGRUBY) %alias add "<<"; #endif /* * add node as child * */ WsXmlNodeH add(WsXmlNodeH node) { ws_xml_duplicate_tree( $self, node ); return $self; } #if defined(SWIGRUBY) /* * iterate over children * * See also XmlNode#next * * XmlNode#each iterates over children, XmlNode#next over siblings * * can be limited to children with specific name (and specific namespace) * * for array-like constructs, e.g * * .. * .. * .. * .. * .. * .. * * doc.Parent.each do |child| * ... iterates over all 6 children ... * end * * use XmlNode#next as in * node = doc.OtherChild * while node do * ... do something with node ... * node = node.next * end * * call-seq: * node.each { |XmlNode| ... } * node.each("name") { |XmlNode| ... } * node.each("name", "namespace") { |XmlNode| ... } * */ void each(const char *name = NULL, const char *ns = NULL) { int i = 0; WsXmlNodeH node = $self; int count = ws_xml_get_child_count_by_qname( node, ns, name ); while ( i < count ) { rb_yield( SWIG_NewPointerObj((void*) ws_xml_get_child(node, i, ns, name), SWIGTYPE_p___WsXmlNode, 0)); ++i; } } #endif #if defined(SWIGPYTHON) /* * iterate over children * */ %pythoncode %{ def __iter__(self): r = range(0,self.size()) while r: yield self.get(r.pop(0)) %} #endif #if defined(SWIGRUBY) %alias get "[]"; #endif /* * get child by index * * call-seq: * node.get(42) -> XmlNode * node.get(42, "name") -> XmlNode * node.get(42, "name", "namespace") -> XmlNode * */ WsXmlNodeH get(int i, const char *name = NULL, const char *ns = NULL) { if (i < 0 || i >= ws_xml_get_child_count_by_qname($self,ns,name)) return NULL; return ws_xml_get_child($self, i, ns, name); } /* * get first child by name (and namespace) * * call-seq: * node.get("name") -> XmlNode * node.get("name", "namespace") -> XmlNode * */ WsXmlNodeH get(const char *name, const char *ns = NULL) { return ws_xml_get_child($self, 0, ns, name); } #if defined(SWIGRUBY) /* * get node attribute by index or name * * call-seq: * node.attr(1) -> XmlAttr * node.attr("name") -> XmlAttr * node.attr("name", "namespace") -> XmlAttr * */ WsXmlAttrH attr(VALUE index = Qnil, VALUE namespace = Qnil) { if (NIL_P(index)) { /* nil */ return ws_xml_get_node_attr( $self, 0 ); } else if (FIXNUM_P(index)) { /* numeric */ return ws_xml_get_node_attr( $self, FIX2INT(index) ); } else { /* convert to string */ const char *ns = NULL; const char *name = as_string(index); if (!NIL_P(namespace)) { ns = as_string(namespace); } return ws_xml_find_node_attr( $self, ns, name ); } } #else /* get node attribute */ WsXmlAttrH attr(int index = 0) { return ws_xml_get_node_attr( $self, index ); } #endif /* * count node attribute * * call-seq: * node.attr_count -> Integer * */ int attr_count() { return ws_xml_get_node_attr_count( $self ); } /* * find node attribute by name * * call-seq: * node.attr_find("namespace", "name") -> XmlAttr * */ WsXmlAttrH attr_find( const char *ns, const char *name ) { return ws_xml_find_node_attr( $self, ns, name ); } /* * add attribute to node * * call-seq: * node.attr_add("namespace", "name", "value") -> XmlAttr * */ WsXmlAttrH attr_add( const char *ns, const char *name, const char *value ) { return ws_xml_add_node_attr( $self, ns, name, value ); } /* * get end point reference * * call-seq: * node.epr("namespace", "epr_node_name", Integer embedded) -> EndPointReference * */ epr_t *epr( const char *ns, const char *epr_node_name, int embedded) { return epr_deserialize($self, ns, epr_node_name, embedded); } #if defined(SWIGRUBY) /* * enumerate attributes * * call-seq: * node.each_attr { |XmlAttr| ... } * */ void each_attr() { int i = 0; while ( i < ws_xml_get_node_attr_count( $self ) ) { rb_yield( SWIG_NewPointerObj((void*) ws_xml_get_node_attr($self, i), SWIGTYPE_p___WsXmlAttr, 0)); ++i; } } #endif } /* * Document-class: XmlAttr * * An XmlAttr is a key/value pair representing an attribute of a node. * * An attribute has * * a name (the key) * * a namespace (optional) * * a value * * There is no standalone constructor available for XmlAttr, use * XmlNode.add_attr() to create a new attribute. * */ %rename(XmlAttr) __WsXmlAttr; %nodefault __WsXmlAttr; /* part of WsXmlNode */ struct __WsXmlAttr {}; /* without empty struct, the %rename isn't executed. */ typedef struct __WsXmlAttr* WsXmlAttrH; %extend __WsXmlAttr { #if defined(SWIGRUBY) %alias value "to_s"; #endif /* * get name for attr * * call-seq: * attr.name -> String * */ char *name() { return ws_xml_get_attr_name( $self ); } /* * get namespace for attr * * call-seq: * attr.ns -> String * */ char *ns() { return ws_xml_get_attr_ns( $self ); } /* * get value for attr * * call-seq: * attr.value -> String * */ char *value() { return ws_xml_get_attr_value( $self ); } /* * remove note attribute * * call-seq: * attr.remove -> nil * */ void remove() { ws_xml_remove_node_attr( $self ); } }