XML-PugiXML

 view release on metacpan or  search on metacpan

PugiXML.xs  view on Meta::CPAN

PPCODE:
{
    XPATH_GUARDED {
        xpath_node_set nodes = self->doc->select_nodes(xpath);
        EXTEND(SP, (SSize_t)nodes.size());
        for (xpath_node_set::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
            SV* sv = wrap_xpath_result(aTHX_ *it, ST(0));
            PUSHs(sv_2mortal(sv));
        }
    } END_XPATH_GUARDED;
}

SV*
compile_xpath(XML::PugiXML self, const char* xpath)
CODE:
{
    PERL_UNUSED_VAR(self);
    RETVAL = 0;
    XPATH_GUARDED {
        xpath_query* query = new (std::nothrow) xpath_query(xpath);
        if (!query) {
            croak("Out of memory allocating xpath_query");
        }
        PugiXPath* wrapper = new (std::nothrow) PugiXPath;
        if (!wrapper) {
            delete query;
            croak("Out of memory allocating XPath wrapper");
        }
        wrapper->query = query;

        SV* sv = newSV(0);
        sv_setref_pv(sv, "XML::PugiXML::XPath", (void*)wrapper);
        RETVAL = sv;
    } catch (const xpath_exception& e) {
        snprintf(xpath_err, sizeof(xpath_err), "XPath compilation error: %s", e.what());
    } catch (const std::exception& e) {
        snprintf(xpath_err, sizeof(xpath_err), "Internal XPath compilation error: %s", e.what());
    }
    if (xpath_err[0]) croak("%s", xpath_err);
}
OUTPUT:
    RETVAL

BOOT:
{
    HV* stash = gv_stashpv("XML::PugiXML", GV_ADD);
#define PUGI_CONST(name, val) \
    newCONSTSUB(stash, name, newSVuv((UV)(val)))
    PUGI_CONST("PUGIXML_VERSION",         PUGIXML_VERSION);
    PUGI_CONST("FORMAT_DEFAULT",          format_default);
    PUGI_CONST("FORMAT_INDENT",           format_indent);
    PUGI_CONST("FORMAT_NO_DECLARATION",   format_no_declaration);
    PUGI_CONST("FORMAT_RAW",              format_raw);
    PUGI_CONST("FORMAT_WRITE_BOM",        format_write_bom);
    PUGI_CONST("FORMAT_INDENT_ATTRIBUTES", format_indent_attributes);
    PUGI_CONST("FORMAT_NO_EMPTY_ELEMENT_TAGS", format_no_empty_element_tags);
    PUGI_CONST("PARSE_DEFAULT",           parse_default);
    PUGI_CONST("PARSE_MINIMAL",           parse_minimal);
    PUGI_CONST("PARSE_PI",                parse_pi);
    PUGI_CONST("PARSE_COMMENTS",          parse_comments);
    PUGI_CONST("PARSE_CDATA",             parse_cdata);
    PUGI_CONST("PARSE_WS_PCDATA",         parse_ws_pcdata);
    PUGI_CONST("PARSE_WS_PCDATA_SINGLE",  parse_ws_pcdata_single);
    PUGI_CONST("PARSE_ESCAPES",           parse_escapes);
    PUGI_CONST("PARSE_EOL",               parse_eol);
    PUGI_CONST("PARSE_DECLARATION",       parse_declaration);
    PUGI_CONST("PARSE_DOCTYPE",           parse_doctype);
    PUGI_CONST("PARSE_FULL",              parse_full);
    PUGI_CONST("NODE_NULL",               node_null);
    PUGI_CONST("NODE_DOCUMENT",           node_document);
    PUGI_CONST("NODE_ELEMENT",            node_element);
    PUGI_CONST("NODE_PCDATA",             node_pcdata);
    PUGI_CONST("NODE_CDATA",              node_cdata);
    PUGI_CONST("NODE_COMMENT",            node_comment);
    PUGI_CONST("NODE_PI",                 node_pi);
    PUGI_CONST("NODE_DECLARATION",        node_declaration);
    PUGI_CONST("NODE_DOCTYPE",            node_doctype);
#undef PUGI_CONST
}


MODULE = XML::PugiXML  PACKAGE = XML::PugiXML::Node

void
DESTROY(XML::PugiXML::Node self)
CODE:
{
    SvREFCNT_dec(self->doc_sv);
    delete self;
}

SV*
name(XML::PugiXML::Node self)
CODE:
{
    CHECK_NODE_ALIVE(self);
    RETVAL = newSVpv_utf8(aTHX_ self->node.name());
}
OUTPUT:
    RETVAL

SV*
value(XML::PugiXML::Node self)
CODE:
{
    CHECK_NODE_ALIVE(self);
    RETVAL = newSVpv_utf8(aTHX_ self->node.value());
}
OUTPUT:
    RETVAL

SV*
text(XML::PugiXML::Node self)
CODE:
{
    CHECK_NODE_ALIVE(self);
    RETVAL = newSVpv_utf8(aTHX_ self->node.text().get());
}
OUTPUT:
    RETVAL

SV*
parent(XML::PugiXML::Node self)
CODE:
{
    CHECK_NODE_ALIVE(self);
    RETVAL = wrap_node(aTHX_ self->node.parent(), self->doc_sv);
}
OUTPUT:
    RETVAL

SV*
child(XML::PugiXML::Node self, const char* name)

PugiXML.xs  view on Meta::CPAN

OUTPUT:
    RETVAL

SV*
prepend_child(XML::PugiXML::Node self, nul_safe_pv name)
CODE:
{
    CHECK_NODE_ALIVE(self);
    xml_node child = self->node.prepend_child(name);
    RETVAL = wrap_node(aTHX_ child, self->doc_sv);
}
OUTPUT:
    RETVAL

SV*
ensure_child(XML::PugiXML::Node self, nul_safe_pv name)
CODE:
{
    CHECK_NODE_ALIVE(self);
    /* get-or-create the first child element of this name. pugixml 1.16 added a
       native ensure_child; emulate it on older libraries (child-or-append) so
       the binding still builds against a system pugixml < 1.16. */
#if PUGIXML_VERSION >= 1160
    xml_node child = self->node.ensure_child(name);
#else
    xml_node child = self->node.child(name);
    if (!child) child = self->node.append_child(name);
#endif
    RETVAL = wrap_node(aTHX_ child, self->doc_sv);
}
OUTPUT:
    RETVAL

SV*
insert_child_before(XML::PugiXML::Node self, nul_safe_pv name, XML::PugiXML::Node ref_node)
CODE:
{
    CHECK_NODE_ALIVE(self);
    CHECK_NODE_ALIVE(ref_node);
    CHECK_SAME_DOC(self, ref_node);
    xml_node child = self->node.insert_child_before(name, ref_node->node);
    RETVAL = wrap_node(aTHX_ child, self->doc_sv);
}
OUTPUT:
    RETVAL

SV*
insert_child_after(XML::PugiXML::Node self, nul_safe_pv name, XML::PugiXML::Node ref_node)
CODE:
{
    CHECK_NODE_ALIVE(self);
    CHECK_NODE_ALIVE(ref_node);
    CHECK_SAME_DOC(self, ref_node);
    xml_node child = self->node.insert_child_after(name, ref_node->node);
    RETVAL = wrap_node(aTHX_ child, self->doc_sv);
}
OUTPUT:
    RETVAL

SV*
append_cdata(XML::PugiXML::Node self, nul_safe_pv content)
CODE:
{
    CHECK_NODE_ALIVE(self);
    xml_node cdata = self->node.append_child(node_cdata);
    if (cdata) {
        cdata.set_value(content);
    }
    RETVAL = wrap_node(aTHX_ cdata, self->doc_sv);
}
OUTPUT:
    RETVAL

SV*
append_comment(XML::PugiXML::Node self, nul_safe_pv content)
CODE:
{
    CHECK_NODE_ALIVE(self);
    xml_node comment = self->node.append_child(node_comment);
    if (comment) {
        comment.set_value(content);
    }
    RETVAL = wrap_node(aTHX_ comment, self->doc_sv);
}
OUTPUT:
    RETVAL

int
type(XML::PugiXML::Node self)
CODE:
{
    CHECK_NODE_ALIVE(self);
    RETVAL = (int)self->node.type();
}
OUTPUT:
    RETVAL

SV*
path(XML::PugiXML::Node self, char delimiter = '/')
CODE:
{
    CHECK_NODE_ALIVE(self);
    RETVAL = 0;
    XPATH_GUARDED {
        std::string p = self->node.path(delimiter);
        RETVAL = new_utf8_svpvn(aTHX_ p.c_str(), p.length());
    } catch (const std::exception& e) {
        snprintf(xpath_err, sizeof(xpath_err), "path error: %s", e.what());
    }
    if (xpath_err[0]) croak("%s", xpath_err);
}
OUTPUT:
    RETVAL

SV*
find_child_by_attribute(XML::PugiXML::Node self, const char* name, const char* attr_name, const char* attr_value)
CODE:
{
    CHECK_NODE_ALIVE(self);
    xml_node child = self->node.find_child_by_attribute(name, attr_name, attr_value);
    RETVAL = wrap_node(aTHX_ child, self->doc_sv);
}
OUTPUT:
    RETVAL

SV*
root(XML::PugiXML::Node self)
CODE:
{



( run in 0.568 second using v1.01-cache-2.11-cpan-6aa56a78535 )