Libxml
Thin wrapper for Libxml2 using NIF
NIF
NIF for Libxml2 are defined in Libxml.Nif.
These functions are thin wrapper. You should manage yourself the memory allocation and deallocation.
For example, Libxml.Nif.xml_read_memory/1 corresponds to xmlReadMemory in Libxml2.
xmlReadMemory returns xmlDocPtr pointer. Libxml.Nif.xml_read_memory/1 returns the pointer value as integer.
If you want to see inside the xmlDocPtr pointer, call Libxml.Nif.get_xml_node/1.
If you want to apply a value to xmlDocPtr, call Libxml.Nif.set_xml_node/2.
content = "<doc></doc>"
{:ok, docptr} = Libxml.Nif.xml_read_memory(content)
{:ok, docvalue} = Libxml.Nif.get_xml_node(docptr)
#IO.inspect docvalue
# output:
# %{children: 140639374148016, doc: 140639374150976, last: 140639374148016,
# name: 0, next: 0, parent: 0, prev: 0, private: 0, type: 9}
assert docvalue.type == 9 # XML_DOCUMENT_NODE
# update
docvalue = %{docvalue | private: 100}
:ok = Libxml.Nif.set_xml_node(docptr, docvalue) # apply
# check
{:ok, docvalue} = Libxml.Nif.get_xml_node(docptr)
assert docvalue.private == 100
# free a doc node
Libxml.Nif.xml_free_doc(docptr)Typed Thin Wrapper
NIF is incovinient, so this library provides typed thin wrapper.
For example, Libxml.read_memory/1 corresponds to xmlReadMemory in Libxml2.
Libxml.read_memory/1 returns a value type of %Libxml.Node{}.
%Libxml.Node{} has :pointer field. The pointer value returned the function is assined this field.
If you want to see inside the xmlDocPtr pointer, call Libxml.Node.extract/1.
If you want to apply a value to xmlDocPtr, call Libxml.Node.apply/1.
content = "<doc></doc>"
node = %Libxml.Node{} = Libxml.read_memory(content)
node = Libxml.Node.extract(node)
#IO.inspect node
# output:
# %Libxml.Node{children: %Libxml.Node{children: nil, doc: nil, last: nil,
# more: nil, name: nil, next: nil, parent: nil, pointer: 140551835942432,
# prev: nil, private: nil, type: nil},
# doc: %Libxml.Node{children: nil, doc: nil, last: nil, more: nil, name: nil,
# next: nil, parent: nil, pointer: 140551835942128, prev: nil, private: nil,
# type: nil},
# last: %Libxml.Node{children: nil, doc: nil, last: nil, more: nil, name: nil,
# next: nil, parent: nil, pointer: 140551835942432, prev: nil, private: nil,
# type: nil}, more: %Libxml.Node.TODO{}, name: nil, next: nil, parent: nil,
# pointer: 140551835942128, prev: nil, private: 0, type: :document_node}
assert node.type == :document_node
# update
node = %{node | private: 100}
:ok = Libxml.Node.apply(node) # apply
# check
node = Libxml.Node.extract(node)
assert node.private == 100
# free a doc node
Libxml.free_doc(node)