xmerl exporting with namespace?
Fredrik Thulin
ft@REDACTED
Wed Jun 14 11:35:26 CEST 2006
Hi
I am most unfortunate, I have to not only parse XML documents, but also
try to merge XML documents ;(.
I think the easiest way to explain my problem is with the attached
module.
The problem is that x:output_tuples() (which uses
xmerl:export_simple_content(Tuples, xmerl_xml) produces the following :
<pr:tuple id="sd04cf079">
<pr:status><pr:basic>open</pr:basic></pr:status>
<pr:note>Idle</pr:note>
<rpid:user-input
last-input="2006-06-13T21:40:17Z">idle</rpid:user-input>
<pr:timestamp>2006-06-13T21:40:17Z</pr:timestamp>
</pr:tuple>
To put that into another XML document, I need the namespace information
that _was_ available in the xmlElement record outputted, something like
<pr:tuple xmlns:pr="urn:ietf:params:xml:ns:pidf" id="sd04cf079">
<pr:status><pr:basic>open</pr:basic></pr:status>
<pr:note>Idle</pr:note>
<rpid:user-input xmlns:rpid="urn:ietf:params:xml:ns:pidf:rpid"
last-input="2006-06-13T21:40:17Z">idle</rpid:user-input>
<pr:timestamp>2006-06-13T21:40:17Z</pr:timestamp>
</pr:tuple>
(I'm no XML expert, far from). Is that possible somehow?
/Fredrik
-------------- next part --------------
-module(x).
-compile(export_all).
-include_lib("xmerl/include/xmerl.hrl").
%% example SIP/SIMPLE Presence PIDF XML document
in() ->
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
"<pr:presence xmlns:pr=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:ft22@REDACTED\""
" xmlns:caps=\"urn:ietf:params:xml:ns:pidf:caps\""
" xmlns:cipid=\"urn:ietf:params:xml:ns:pidf:cipid\""
" xmlns:counterpath=\"www.counterpath.com/presence/ext\""
" xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\""
" xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\">\n"
" <pr:tuple id=\"sd04cf079\">\n"
" <pr:status><pr:basic>open</pr:basic></pr:status>\n"
" <pr:note>Idle</pr:note>\n"
" <rpid:user-input last-input=\"2006-06-13T21:40:17Z\">idle</rpid:user-input>\n"
" <pr:timestamp>2006-06-13T21:40:17Z</pr:timestamp>\n"
" </pr:tuple>\n"
" <dm:person id=\"p8652f666\">\n"
" <dm:note>Idle</dm:note>\n"
" </dm:person>\n"
"</pr:presence>\n".
%% parse the example XML document, namespace_conformant
parse() ->
parse( in() ).
parse(Src) when is_list(Src) ->
try xmerl_scan:string(Src, [{namespace_conformant, true}]) of
{XML, []} ->
XML;
_ ->
{error, bad_xml}
catch
_: _ ->
{error, failed_parsing}
end.
%% get the PIDF tuples (<pr:tuple ...> in the XML source)
get_tuples() ->
XML = parse(),
get_tuples(XML).
get_tuples(XML) when is_record(XML, xmlElement) ->
get_xml_elements(tuple, XML#xmlElement.content).
get_xml_elements(Name, In) when is_atom(Name), is_list(In) ->
get_xml_elements2(Name, In, []).
get_xml_elements2(Name, [#xmlElement{name = Name} = H | T], Res) ->
get_xml_elements2(Name, T, [H | Res]);
get_xml_elements2(Name, [#xmlElement{expanded_name = {_URI, Name}} = H | T], Res) ->
get_xml_elements2(Name, T, [H | Res]);
get_xml_elements2(Name, [_H | T], Res) ->
get_xml_elements2(Name, T, Res);
get_xml_elements2(_Name, [], Res) ->
lists:reverse(Res).
%% Output only the PIDF tuple(s), this is where I am missing the namespace information
output_tuples() ->
Tuples = get_tuples(),
output_tuples(Tuples).
output_tuples(Tuples) when is_list(Tuples) ->
Out = xmerl:export_simple_content(Tuples, xmerl_xml),
io:format("~s~n~n", [lists:flatten(Out)]),
ok.
More information about the erlang-questions
mailing list