Skip to content

Commit 1e11fbc

Browse files
committed
dump (string & show) and save_file
1 parent 7163b55 commit 1e11fbc

File tree

7 files changed

+128
-9
lines changed

7 files changed

+128
-9
lines changed

src/MiniDOM.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ module MiniDOM
1414
find_element, get_elements_by_tagname,
1515

1616
# document
17-
XMLDocument,
18-
parse_file, parse_string, version, encoding, compression, standalone,
19-
docelement
17+
XMLDocument, version, encoding, compression, standalone, docelement,
18+
parse_file, parse_string, save_file
19+
2020

2121
include("clib.jl")
2222
include("errors.jl")
2323

24+
include("utils.jl")
2425
include("nodes.jl")
2526
include("document.jl")
2627
end

src/clib.jl

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,27 @@ _xmlfree{T}(p::Ptr{T}) = ccall(:free, Void, (Ptr{T},), p)
2929
# pre-condition: p is not null
3030
_xcopystr(p::Xstr) = (r = bytestring(p); _xmlfree(p); r)
3131

32+
# buffer
33+
34+
@lx2func xmlBufferCreateSize
35+
@lx2func xmlBufferFree
36+
@lx2func xmlBufferLength
37+
@lx2func xmlBufferContent
38+
3239
# functions for nodes
3340

3441
@lx2func xmlNodeGetContent
3542
@lx2func xmlGetProp
3643
@lx2func xmlFirstElementChild
3744
@lx2func xmlNextElementSibling
45+
@lx2func xmlNodeDump
3846

3947
# functions for documents
4048

49+
@lx2func xmlDocGetRootElement
50+
@lx2func xmlFreeDoc
4151
@lx2func xmlParseFile
4252
@lx2func xmlParseMemory
43-
@lx2func xmlFreeDoc
44-
@lx2func xmlDocGetRootElement
45-
53+
@lx2func xmlDocDumpMemoryEnc
54+
@lx2func xmlSaveFileEnc
4655

src/document.jl

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ function docelement(xdoc::XMLDocument)
5858
XMLElement(pr)
5959
end
6060

61+
62+
#### construction & free
63+
64+
function free(xdoc::XMLDocument)
65+
ccall(xmlFreeDoc, Void, (Ptr{Void},), xdoc.ptr)
66+
xdoc.ptr = nullptr
67+
end
68+
69+
6170
#### parse and free
6271

6372
function parse_file(filename::ASCIIString)
@@ -72,8 +81,26 @@ function parse_string(s::ASCIIString)
7281
XMLDocument(p)
7382
end
7483

75-
function free(xdoc::XMLDocument)
76-
ccall(xmlFreeDoc, Void, (Ptr{Void},), xdoc.ptr)
77-
xdoc.ptr = nullptr
84+
85+
#### output
86+
87+
function save_file(xdoc::XMLDocument, filename::ASCIIString; encoding::ASCIIString="utf-8")
88+
ret = ccall(xmlSaveFileEnc, Cint, (Ptr{Cchar}, Xptr, Ptr{Cchar}),
89+
filename, xdoc.ptr, encoding)
90+
if ret < 0
91+
throw(XMLWriteError("Failed to save XML to file $filename"))
92+
end
93+
return int(ret) # number of bytes written
7894
end
7995

96+
function Base.string(xdoc::XMLDocument; encoding::ASCIIString="utf-8")
97+
buf_out = Array(Xstr, 1)
98+
len_out = Array(Cint, 1)
99+
ccall(xmlDocDumpMemoryEnc, Void, (Xptr, Ptr{Xstr}, Ptr{Cint}, Ptr{Cchar}),
100+
xdoc.ptr, buf_out, len_out, encoding)
101+
_xcopystr(buf_out[1])
102+
end
103+
104+
Base.show(io::IO, xdoc::XMLDocument) = println(io, Base.string(xdoc))
105+
106+

src/errors.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ end
1111
immutable XMLAttributeNotFound <: XMLError
1212
end
1313

14+
immutable XMLWriteError <: XMLError
15+
msg::ASCIIString
16+
end
17+
1418
const dom_exception_causes = [
1519
"Index size error", # 1
1620
"DOM string size error", # 2

src/nodes.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,23 @@ function content(nd::XMLNode)
159159
(pct != nullptr ? _xcopystr(pct) : "")::ASCIIString
160160
end
161161

162+
# dumping
163+
164+
const DEFAULT_DUMPBUFFER_SIZE = 4096
165+
166+
function Base.string(nd::XMLNode)
167+
buf = XBuffer(DEFAULT_DUMPBUFFER_SIZE)
168+
ccall(xmlNodeDump, Cint, (Xptr, Xptr, Xptr, Cint, Cint),
169+
buf.ptr, nd._struct.doc, nd.ptr, 0, 0)
170+
r = content(buf)
171+
free(buf)
172+
return r
173+
end
174+
175+
function Base.show(io::IO, nd::XMLNode)
176+
println(io, Base.string(nd))
177+
end
178+
162179

163180
#######################################
164181
#
@@ -185,6 +202,9 @@ has_children(x::XMLElement) = has_children(x.node)
185202
child_nodes(x::XMLElement) = child_nodes(x.node)
186203
content(x::XMLElement) = content(x.node)
187204

205+
Base.string(x::XMLElement) = Base.string(x.node)
206+
Base.show(io::IO, x::XMLElement) = Base.show(x.node)
207+
188208
# attribute access
189209

190210
function attribute(x::XMLElement, name::ASCIIString)

src/utils.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Utilities
2+
3+
##### Buffer
4+
5+
immutable XBuffer
6+
ptr::Xptr
7+
8+
function XBuffer(bytes::Integer)
9+
p = ccall(xmlBufferCreateSize, Xptr, (Csize_t,), bytes)
10+
p != nullptr || error("Failed to create buffer of $bytes bytes.")
11+
new(p)
12+
end
13+
end
14+
15+
free(buf::XBuffer) = ccall(xmlBufferFree, Void, (Xptr,), buf.ptr)
16+
17+
Base.length(buf::XBuffer) = int(ccall(xmlBufferLength, Cint, (Xptr,), buf.ptr))
18+
19+
content(buf::XBuffer) = bytestring(ccall(xmlBufferContent, Xstr, (Xptr,), buf.ptr))
20+
21+

test/dump.jl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using MiniDOM
2+
3+
# document
4+
5+
docstr = """
6+
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
7+
<bookstore>
8+
<book category="COOKING" tag="first">
9+
<title lang="en">Everyday Italian</title>
10+
<author>Giada De Laurentiis</author>
11+
<year>2005</year>
12+
<price>30.00</price>
13+
</book>
14+
<book category="CHILDREN">
15+
<title lang="en">Harry Potter</title>
16+
<author>J K. Rowling</author>
17+
<year>2005</year>
18+
<price>29.99</price>
19+
</book>
20+
</bookstore>
21+
"""
22+
23+
xdoc = parse_string(docstr)
24+
25+
println("Document:")
26+
println("=====================")
27+
show(xdoc)
28+
29+
# save_file(xdoc, "tt.xml")
30+
31+
println("Root Element:")
32+
println("=====================")
33+
xroot = docelement(xdoc)
34+
show(xroot)
35+
36+
free(xdoc)
37+

0 commit comments

Comments
 (0)