Skip to content

Commit 570cfa6

Browse files
committed
XML document construction
1 parent 1e11fbc commit 570cfa6

File tree

8 files changed

+86
-5
lines changed

8 files changed

+86
-5
lines changed

src/MiniDOM.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ module MiniDOM
1313
child_nodes, has_children, attributes, has_attributes, child_elements,
1414
find_element, get_elements_by_tagname,
1515

16+
new_node, add_child, new_child, add_text, set_attribute,
17+
1618
# document
17-
XMLDocument, version, encoding, compression, standalone, docelement,
18-
parse_file, parse_string, save_file
19+
XMLDocument, version, encoding, compression, standalone, root,
20+
parse_file, parse_string, save_file, set_root, create_root
1921

2022

2123
include("clib.jl")

src/clib.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,16 @@ _xcopystr(p::Xstr) = (r = bytestring(p); _xmlfree(p); r)
4444
@lx2func xmlNextElementSibling
4545
@lx2func xmlNodeDump
4646

47+
@lx2func xmlNewNode
48+
@lx2func xmlAddChild
49+
@lx2func xmlNewText
50+
@lx2func xmlSetProp
51+
4752
# functions for documents
4853

4954
@lx2func xmlDocGetRootElement
55+
@lx2func xmlDocSetRootElement
56+
@lx2func xmlNewDoc
5057
@lx2func xmlFreeDoc
5158
@lx2func xmlParseFile
5259
@lx2func xmlParseMemory

src/document.jl

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,20 @@ type XMLDocument
4545

4646
new(ptr, s)
4747
end
48+
49+
function XMLDocument()
50+
# create an empty document
51+
ptr = ccall(xmlNewDoc, Xptr, (Ptr{Cchar},), "1.0")
52+
XMLDocument(ptr)
53+
end
4854
end
4955

5056
version(xdoc::XMLDocument) = bytestring(xdoc._struct.version)
5157
encoding(xdoc::XMLDocument) = bytestring(xdoc._struct.encoding)
5258
compression(xdoc::XMLDocument) = int(xdoc._struct.compression)
5359
standalone(xdoc::XMLDocument) = int(xdoc._struct.standalone)
5460

55-
function docelement(xdoc::XMLDocument)
61+
function root(xdoc::XMLDocument)
5662
pr = ccall(xmlDocGetRootElement, Ptr{Void}, (Ptr{Void},), xdoc.ptr)
5763
pr != nullptr || throw(XMLNoRootError())
5864
XMLElement(pr)
@@ -66,6 +72,15 @@ function free(xdoc::XMLDocument)
6672
xdoc.ptr = nullptr
6773
end
6874

75+
function set_root(xdoc::XMLDocument, xroot::XMLElement)
76+
ccall(xmlDocSetRootElement, Xptr, (Xptr, Xptr), xdoc.ptr, xroot.node.ptr)
77+
end
78+
79+
function create_root(xdoc::XMLDocument, name::ASCIIString)
80+
xroot = new_element(name)
81+
set_root(xdoc, xroot)
82+
return xroot
83+
end
6984

7085
#### parse and free
7186

src/errors.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ immutable XMLWriteError <: XMLError
1515
msg::ASCIIString
1616
end
1717

18+
immutable XMLTreeError <: XMLError
19+
msg::ASCIIString
20+
end
21+
1822
const dom_exception_causes = [
1923
"Index size error", # 1
2024
"DOM string size error", # 2

src/nodes.jl

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,41 @@ function get_elements_by_tagname(x::XMLElement, n::ASCIIString)
249249
return lst
250250
end
251251

252+
253+
#######################################
254+
#
255+
# XML Tree Construction
256+
#
257+
#######################################
258+
259+
function new_element(name::ASCIIString)
260+
p = ccall(xmlNewNode, Xptr, (Xptr, Xstr), nullptr, name)
261+
XMLElement(p)
262+
end
263+
264+
function add_child(xparent::XMLElement, xchild::XMLNode)
265+
p = ccall(xmlAddChild, Xptr, (Xptr, Xptr), xparent.node.ptr, xchild.ptr)
266+
p != nullptr || throw(XMLTreeError("Failed to add a child node."))
267+
end
268+
269+
add_child(xparent::XMLElement, xchild::XMLElement) = add_child(xparent, xchild.node)
270+
271+
function new_child(xparent::XMLElement, name::ASCIIString)
272+
xc = new_element(name)
273+
add_child(xparent, xc)
274+
return xc
275+
end
276+
277+
function new_textnode(txt::ASCIIString)
278+
p = ccall(xmlNewText, Xptr, (Xstr,), txt)
279+
XMLNode(p)
280+
end
281+
282+
add_text(x::XMLElement, txt::ASCIIString) = add_child(x, new_textnode(txt))
283+
284+
function set_attribute(x::XMLElement, name::ASCIIString, val::ASCIIString)
285+
a = ccall(xmlSetProp, Xptr, (Xptr, Xstr, Xstr), x.node.ptr, name, val)
286+
return XMLAttr(a)
287+
end
288+
289+

test/create.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using MiniDOM
2+
3+
xdoc = XMLDocument()
4+
5+
xroot = create_root(xdoc, "States")
6+
7+
xs1 = new_child(xroot, "State")
8+
add_text(xs1, "Massachusetts")
9+
set_attribute(xs1, "tag", "MA")
10+
11+
xs2 = new_child(xroot, "State")
12+
add_text(xs2, "Illinois")
13+
set_attribute(xs2, "tag", "MA")
14+
15+
show(xdoc)

test/dump.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ show(xdoc)
3030

3131
println("Root Element:")
3232
println("=====================")
33-
xroot = docelement(xdoc)
33+
xroot = root(xdoc)
3434
show(xroot)
3535

3636
free(xdoc)

test/parse.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ xdoc = parse_string(docstr)
3030

3131
# root node
3232

33-
xroot = docelement(xdoc)
33+
xroot = root(xdoc)
3434

3535
@test isa(xroot, XMLElement)
3636
@test is_elementnode(xroot)

0 commit comments

Comments
 (0)