aboutsummaryrefslogtreecommitdiffstats
path: root/lib/xmerl
diff options
context:
space:
mode:
authorAnthony Ramine <nox@dev-extend.eu>2010-12-18 23:49:15 +0100
committerLars Thorsen <lars@erlang.org>2011-11-11 11:58:43 +0100
commitfcf6b58a1f7a2eafa0db79f1715db1c193c3f346 (patch)
tree078115458f26ac89a543c3a427090a3b78447ed0 /lib/xmerl
parent7fc95c00764fc13d2e3e676cca1a66be5d672c41 (diff)
downloadotp-fcf6b58a1f7a2eafa0db79f1715db1c193c3f346.tar.gz
otp-fcf6b58a1f7a2eafa0db79f1715db1c193c3f346.tar.bz2
otp-fcf6b58a1f7a2eafa0db79f1715db1c193c3f346.zip
Add `default_attrs` option
When `default_attrs` is `true`, any attribute with a default value defined in the doctype but not in the attribute axis of the currently scanned element is added to it.
Diffstat (limited to 'lib/xmerl')
-rw-r--r--lib/xmerl/include/xmerl.hrl1
-rw-r--r--lib/xmerl/src/xmerl_scan.erl34
2 files changed, 33 insertions, 2 deletions
diff --git a/lib/xmerl/include/xmerl.hrl b/lib/xmerl/include/xmerl.hrl
index 9c471c437f..2e18e216e2 100644
--- a/lib/xmerl/include/xmerl.hrl
+++ b/lib/xmerl/include/xmerl.hrl
@@ -156,6 +156,7 @@
doctype_name,
doctype_DTD = internal, % internal | DTDId
document = false,
+ default_attrs = false,
rules,
keep_rules = false, % delete (ets) tab if false
namespace_conformant = false, % true | false
diff --git a/lib/xmerl/src/xmerl_scan.erl b/lib/xmerl/src/xmerl_scan.erl
index 303fc26550..9e3e6ee728 100644
--- a/lib/xmerl/src/xmerl_scan.erl
+++ b/lib/xmerl/src/xmerl_scan.erl
@@ -103,6 +103,9 @@
%% <dt><code>{document, Flag}</code></dt>
%% <dd>Set to 'true' if xmerl should return a complete XML document
%% as an xmlDocument record (default 'false').</dd>
+%% <dt><code>{default_attrs, Flag}</code></dt>
+%% <dd>Set to 'true' if xmerl should add to elements missing attributes
+%% with a defined default value (default 'false').</dd>
%% </dl>
%% @type document() = xmlElement() | xmlDocument(). <p>
%% The document returned by <tt>xmerl_scan:string/[1,2]</tt> and
@@ -391,6 +394,8 @@ initial_state([{doctype_DTD,DTD}|T], S) ->
initial_state(T,S#xmerl_scanner{doctype_DTD = DTD});
initial_state([{document, F}|T], S) when is_boolean(F) ->
initial_state(T,S#xmerl_scanner{document = F});
+initial_state([{default_attrs, F}|T], S) when is_boolean(F) ->
+ initial_state(T,S#xmerl_scanner{default_attrs = F});
initial_state([{text_decl,Bool}|T], S) ->
initial_state(T,S#xmerl_scanner{text_decl=Bool});
initial_state([{environment,Env}|T], S) ->
@@ -2161,6 +2166,14 @@ scan_element(T, S, Pos, Name, StartL, StartC, Attrs, Lang, Parents,
scan_element(T4, S5, Pos, Name, StartL, StartC, [Attr|Attrs],
Lang, Parents, NSI, NewNS, SpaceDefault).
+get_default_attrs(S = #xmerl_scanner{rules_read_fun = Read}, ElemName) ->
+ case Read(elem_def, ElemName, S) of
+ #xmlElement{attributes = Attrs} ->
+ [ {AttName, AttValue} ||
+ {AttName, _, AttValue, _, _} <- Attrs, AttValue =/= no_value ];
+ _ -> []
+ end.
+
get_att_type(S=#xmerl_scanner{rules_read_fun=Read},AttName,ElemName) ->
case Read(elem_def,ElemName,S) of
#xmlElement{attributes = Attrs} ->
@@ -2190,6 +2203,23 @@ processed_whole_element(S=#xmerl_scanner{hook_fun = _Hook,
Pos, Name, Attrs, Lang, Parents, NSI, Namespace) ->
Language = check_language(Attrs, Lang),
+ AllAttrs =
+ case S#xmerl_scanner.default_attrs of
+ true ->
+ [ #xmlAttribute{name = AttName,
+ parents = [{Name, Pos} | Parents],
+ language = Lang,
+ nsinfo = NSI,
+ namespace = Namespace,
+ value = AttValue,
+ normalized = true} ||
+ {AttName, AttValue} <- get_default_attrs(S, Name),
+ AttValue =/= no_value,
+ not lists:keymember(AttName, #xmlAttribute.name, Attrs) ];
+ false ->
+ Attrs
+ end,
+
{ExpName, ExpAttrs} =
case S#xmerl_scanner.namespace_conformant of
true ->
@@ -2209,10 +2239,10 @@ processed_whole_element(S=#xmerl_scanner{hook_fun = _Hook,
A#xmlAttribute.name,
A#xmlAttribute.nsinfo,
% NSI,
- TempNamespace, S)} || A <- Attrs],
+ TempNamespace, S)} || A <- AllAttrs],
{expanded_name(Name, NSI, Namespace, S), ExpAttrsX};
false ->
- {Name, Attrs}
+ {Name, AllAttrs}
end,
#xmlElement{name = Name,