# 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`](http://xmlsoft.org/html/libxml-parser.html#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`.
```elixir
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`.
```elixir
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)
```