Skip to content

Commit

Permalink
writing w. empty prefix and elementFormDefault="unqualified". todo: a…
Browse files Browse the repository at this point in the history
…ttributes!
  • Loading branch information
willemdj committed Jan 8, 2016
1 parent 8d3364a commit b368a8d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 24 deletions.
5 changes: 4 additions & 1 deletion src/erlsom.hrl
Expand Up @@ -23,5 +23,8 @@
%%% ====================================================================

%% prefix=the prefix that will be used in the result
-record(ns, {uri, prefix}).
-record(ns, {uri,
prefix,
efd :: qualified | unqualified % elementFormDefault
}).
-record(qname, {uri, localPart, prefix, mappedPrefix}).
34 changes: 24 additions & 10 deletions src/erlsom_compile.erl
Expand Up @@ -167,7 +167,7 @@ compile_internal(Xsd, Options, Parsed) ->
end,
IncludeFiles = case lists:keysearch('include_files', 1, Options) of
{value, {_, Files}} -> Files;
_ -> Namespaces %% the two options are mutually exclusive
_ -> []
end,
%% the 'already_imported' option is necessary in case the imports
%% are in separate XSDs that refer to each other. This happens
Expand All @@ -180,7 +180,7 @@ compile_internal(Xsd, Options, Parsed) ->
put(erlsom_elementPrefix, ElementPrefix),
%% first we translate to an intermediate format, in a final pass we will add
%% things like sequence numbers and element counts.
Ns = [#ns{prefix="xsd", uri="http://www.w3.org/2001/XMLSchema"} | Namespaces],
Ns = [#ns{prefix="xsd", uri="http://www.w3.org/2001/XMLSchema", efd = qualified} | Namespaces],
ParsingResult = case Parsed of
false -> erlsom_parseXsd:parseXsd(Xsd, Ns);
_ -> Xsd
Expand All @@ -201,8 +201,8 @@ compile_parsed_xsd(ParsedXsd, Prefix, Namespaces) ->

compile_parsed_xsd(ParsedXsd, Prefix, Namespaces, IncludeFun, IncludeDirs, IncludeFiles,
IncludeAnyAttribs, ValueFun, AlreadyImported) ->
%% InfoRecord will contain some information required along the way
TargetNs = ParsedXsd#schemaType.targetNamespace,
Efd = map_efd(ParsedXsd#schemaType.elementFormDefault),
case Prefix of
undefined ->
Pf1 = "",
Expand All @@ -219,26 +219,26 @@ compile_parsed_xsd(ParsedXsd, Prefix, Namespaces, IncludeFun, IncludeDirs, Inclu
case lists:keyfind(TargetNs, #ns.uri, Namespaces) of
false ->
Nsp = Pf1,
Nss = [#ns{prefix = Pf2, uri = TargetNs} | Namespaces];
#ns{prefix = Pf} ->
Nss = [#ns{prefix = Pf2, uri = TargetNs, efd = Efd} | Namespaces];
#ns{prefix = Pf} = KnownNs ->
case Pf of
undefined -> Nsp = "";
_ -> Nsp = Pf ++ ":"
end,
Nss = Namespaces
Nss = lists:keystore(TargetNs, #ns.uri, Namespaces, KnownNs#ns{efd = Efd})
end
end,
ImportedNs = [Uri || {Uri, _} <- AlreadyImported],
ImportedNsMapping = [#ns{prefix = P, uri = U} || {U, P} <- AlreadyImported],
ToBeImportedNsMapping = [#ns{prefix = P, uri = U} || {U, P, _} <- IncludeFiles],
%ImportedNsMapping = [#ns{prefix = P, uri = U} || {U, P} <- AlreadyImported],
%ToBeImportedNsMapping = [#ns{prefix = P, uri = U} || {U, P, _} <- IncludeFiles],
Acc = #p1acc{tns = TargetNs,
includeFun = IncludeFun,
includeDirs = IncludeDirs,
includeFiles = IncludeFiles,
efd = ParsedXsd#schemaType.elementFormDefault,
afd = ParsedXsd#schemaType.attributeFormDefault,
nsp = Nsp,
nss = Nss ++ ToBeImportedNsMapping ++ ImportedNsMapping,
nss = Nss, % ++ ToBeImportedNsMapping, % ++ ImportedNsMapping,
imported = ImportedNs},
case catch transform(ParsedXsd, Acc) of
{error, Message} -> {error, Message};
Expand Down Expand Up @@ -428,9 +428,19 @@ combineInfo(#schemaType{targetNamespace=Tns, elementFormDefault=Efd,
nss = if
Tns == undefined -> Namespaces;
true ->
[#ns{prefix=Prefix, uri=Tns} | Namespaces]
set_efd(Namespaces, Tns, map_efd(Efd), Prefix)
end}.

%% set the efd element (elementFormDefault)
%% This is messy - the point is not to overwrite the Prefix if it exists.
set_efd(Namespaces, Uri, Efd, Prefix) ->
case lists:keyfind(Uri, #ns.uri, Namespaces) of
#ns{} = Record ->
lists:keyreplace(Uri, #ns.uri, Namespaces, Record#ns{efd = Efd});
false ->
lists:keystore(Uri, #ns.uri, Namespaces, #ns{prefix=Prefix, uri=Uri, efd = Efd})
end.

%% globalElementType
%% -record(globalElementType, {name, type, simpleOrComplex}).
transformTypes([#globalElementType{name=Name, type=undefined, simpleOrComplex=SorC,
Expand Down Expand Up @@ -925,3 +935,7 @@ translateNs({Uri, Prefix}) ->
#ns{uri = Uri, prefix = Prefix};
translateNs(#ns{} = X) ->
X.

map_efd(undefined) -> unqualified;
map_efd("unqualified") -> unqualified;
map_efd("qualified") -> qualified.
1 change: 0 additions & 1 deletion src/erlsom_lib.erl
Expand Up @@ -1072,7 +1072,6 @@ prettyPrint(String) ->
{[[Indent, "</", printPf(Prefix), LocalName, ">\n"] | Acc], NewIndentLevel, [], Event, false};
{_, _} ->
%% ignore
io:format("ignore~n"),
In
end
end,
Expand Down
43 changes: 31 additions & 12 deletions src/erlsom_write.erl
Expand Up @@ -322,10 +322,10 @@ processAlternativeValue(Value, Count,
end,

%% deal with namespaces (that is, see if they have to be declared here)
{NamespacesString, NewDeclaredNamespaces4} = processNamespaces(TagAsText, Namespaces, DeclaredNamespaces3),
{NamespacesString, NewDeclaredNamespaces4, Extra_prefix} = processNamespaces(TagAsText, Namespaces, DeclaredNamespaces3),
ResultForThisElement = struct2xml(Value, Elements, [], Model, NewDeclaredNamespaces4, Mixed),
AllAttrs = NamespacesString ++ AttributesString ++ AnyAttrPlusXsiTypeString,
printTag(TagAsText, AllAttrs, ResultForThisElement);
printTag([Extra_prefix, TagAsText], AllAttrs, ResultForThisElement);
true ->
struct2xml(Value, Elements, [], Model, DeclaredNamespaces, Mixed)
end.
Expand Down Expand Up @@ -378,7 +378,7 @@ processAttributes(Struct, ResultSoFar, [#att{nm = Name,
opt = Optional,
tp = Type} | Rest], Namespaces, DeclaredNamespaces) ->
NameAsString = atom_to_list(Name),
{NamespacesString, NewDeclaredNamespaces} = processNamespaces(NameAsString, Namespaces, DeclaredNamespaces),
{NamespacesString, NewDeclaredNamespaces, _Extra_prefix} = processNamespaces(NameAsString, Namespaces, DeclaredNamespaces),
AttributeValue = element(SequenceNr, Struct),
case AttributeValue of
undefined ->
Expand Down Expand Up @@ -520,24 +520,43 @@ processNamespaces(Tag, Namespaces, DeclaredNamespaces = {NamespacesList, Counter
_ ->
throw({error, "Tag " ++ Tag ++ " is not of form [prefix:]localName"})
end,

%% IF
%% prefix is 'undefined' AND
%% namespace for 'undefined' exists AND
%% elementFormDefault (efd) for this ns is 'unqualified' AND
%% the namespace has not be been declared at a higher level
%% THEN
%% put a prefix anyway - make one up. (for now: use "erlsom").


%% declaredNamespaces = [{Prefix, Uri}]
case lists:keysearch(Prefix, 1, NamespacesList) of
{value, _} -> %% already declared
{[], DeclaredNamespaces};
{[], DeclaredNamespaces, ""};
_Else ->
%% find prefix in Model
case lists:keysearch(Prefix, 3, lists:reverse(Namespaces)) of
{value, #ns{uri = Uri}} ->
{value, #ns{uri = Uri, efd = qualified}} ->
Xmlns = case Prefix of
undefined -> " xmlns";
_ -> " xmlns:" ++ Prefix
end,
{Xmlns ++ "=\"" ++ Uri ++ "\"", {[{Prefix, Uri} | NamespacesList], Counter}};
{Xmlns ++ "=\"" ++ Uri ++ "\"", {[{Prefix, Uri} | NamespacesList], Counter}, ""};
{value, #ns{uri = Uri, efd = unqualified}} ->
case Prefix of
undefined ->
Xmlns = " xmlns:erlsom",
Additional_pf = "erlsom:";
_ ->
Xmlns = " xmlns:" ++ Prefix,
Additional_pf = ""
end,
{Xmlns ++ "=\"" ++ Uri ++ "\"", {[{Prefix, Uri} | NamespacesList], Counter}, Additional_pf};
_ ->
case Prefix of
undefined -> {[], DeclaredNamespaces};
"xml" -> {[], DeclaredNamespaces};
undefined -> {[], DeclaredNamespaces, ""};
"xml" -> {[], DeclaredNamespaces, ""};
_ -> throw({error, "Inconsistency in model: namespace is not declared - " ++ Prefix})
end
end
Expand Down Expand Up @@ -664,9 +683,9 @@ printNilValue([#alt{tag=Tag, tp = RecordType}], Value, #model{tps = Types, any_a

%% deal with namespaces (that is, see if they have to be declared here)
TagAsText = atom_to_list(Tag),
{NamespacesString, _DeclaredNamespaces3} = processNamespaces(TagAsText, Namespaces, DeclaredNamespaces2),
{NamespacesString, _DeclaredNamespaces3, Extra_prefix} = processNamespaces(TagAsText, Namespaces, DeclaredNamespaces2),
%% print startTag
StartTag = ["<", TagAsText, NamespacesString, AttributesString, AnyAttributesString,
StartTag = [$<, Extra_prefix, TagAsText, NamespacesString, AttributesString, AnyAttributesString,
" xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"],
%% print end tag
EndTag = ["</", atom_to_list(Tag), ">"],
Expand Down Expand Up @@ -701,8 +720,8 @@ printElement(TextValue, Tag, RealElement, Namespaces, DeclaredNamespaces, QnameN
%% this function is only used in 'leaves' of the struct, so we don't need to store the
%% new declared namespaces (since those would apply only to child-elements, of
%% which there are none)
{NamespacesString, _} = processNamespaces(TagAsText, Namespaces, DeclaredNamespaces),
"<" ++ TagAsText ++ NamespacesString ++ QnameNs ++ ">" ++ TextValue ++ "</" ++ TagAsText ++ ">";
{NamespacesString, _, Extra_prefix} = processNamespaces(TagAsText, Namespaces, DeclaredNamespaces),
[$<, Extra_prefix, TagAsText, NamespacesString, QnameNs, $>, TextValue, "</", TagAsText, $>];
true ->
TextValue
end.
Expand Down

0 comments on commit b368a8d

Please sign in to comment.