[m-rev.] For review: Allow custom functor to element mappings in term_to_xml

Julien Fischer juliensf at cs.mu.OZ.AU
Thu Dec 9 16:44:30 AEDT 2004


On Thu, 9 Dec 2004, Ian MacLarty wrote:

...
> Add a check to see if a DTD can be generated for a type under a custom mapping
> scheme.  This involves checking that the mapping scheme does not generate the
> same element for any two distinct functors that could appear in ground terms of
> the type.
>
> Also do not generate DTDs for types other that discriminated unions, arrays,
s/that/than/

...

> 	that the previously mentioned runtime bug doesn't bite.  This is one
> 	line of code that just needs to be uncommented when the bug is fixed -
Just make this: "This line of code just needs to be uncommented ..."

> 	the line is responsible for getting the field names of the arguments of
> 	a functor.
>
> 	Check that a mapping scheme cannot assign the same element to
> 	two different functors when a DTD is requested.
>
> tests/hard_coded/write_xml.m
> tests/hard_coded/write_xml.exp
> 	Test custom and predefined mapping schemes.
>
>
...

> Index: library/term_to_xml.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/term_to_xml.m,v
> retrieving revision 1.1
> diff -u -r1.1 term_to_xml.m
> --- library/term_to_xml.m	7 Dec 2004 04:55:49 -0000	1.1
> +++ library/term_to_xml.m	9 Dec 2004 01:14:30 -0000
> @@ -14,31 +14,25 @@
>  % an output stream as XML.
>  %
>  % Each functor in a term is given a corresponding well-formed element name
> -% in the XML document.
> +% in the XML document according to a mapping.  Some predefined mappings are
> +% prodice, but user defined mappings may also be used.
s/prodice/provided/

>  %
> -% The element names `String', `Int', `Char' and `Float' are reserved for the
> -% corresponding Mercury builtin types.  The values for these elements are
> -% stored as parsed characater data inside the element.
> -%
> -% Elements for discriminated unions get their name from the functor name and
> -% the type name.  Array element names consist of the string "Array--" followed
> -% by the type name of the elements of the array.  All other types are assigned
> -% the reserved `Unrecognised' element name.
> -%
> -% Each element (including `Unrecognised') may also have certain attributes set:
> +% The following attributes can be set for each XML element:
>  %
>  % functor - the original functor name as returned by
> -% 	deconstruct.deconstruct/5.  This attribute will be present for
> -%	every element except elements for builtin types.
> -%
> -% typename - the type name of the Mercury type the element represents.
> -%	This attribute will also always be present for all elements except
> -%	elements for builtin types.
> +% 	deconstruct.deconstruct/5.
> +%
Should deconstruct.deconstruct/5 be there?

> +% arity - the arity of the functor as returned by deconstruct.deconstruct/5.
> +%
> +% type - the type name of the Mercury type the element represents.
> +%
> +% field - the field name of a discriminated union functor argument if it has
> +% 	one.  XXX Currently field attribute values are not set because of a bug
> +% 	in the runtime system.
>  %

> -% field - discriminated union functor arguments (including those with a
> -%	builtin type) that have a field name will have this attribute set.
> +% The names of the above attributes can also be customized.
>  %


> -% The XML document can also be annotated with a stylesheet reference.  Once a
> +% The XML document can be annotated with a stylesheet reference.  Once a
>  % Mercury term is in XML it can be converted to many different formats using
>  % the appropriate stylesheet.  For example in the extras/xml_stylesheets
>  % distribution there are stylesheets to convert XML documents generated with
> @@ -47,6 +41,21 @@
>  %
>  % To support third parties generating XML which is compatible with the XML
>  % generated by this library, a DTD for a Mercury type can also be generated.
> +% A DTD for a given type and functo-to-element mapping may be generated
s/functo/functor/

> +% provided the following conditions hold:
> +%
> +%	1. If the type is a discriminated union then there must be only
> +%	one top-level functor for the type.  This is because the top
> +%	level functor will be used to generate the document type name.
> +%
> +%	2. The provided functor to element mapping must map each functor
> +%	to a unique element name for every functor that could appear in
> +%	terms of the type.
Remove the word provided there, it's redundant.

> +%
> +%	3. Only types whose terms consist of discriminated unions, arrays
> +%	and the builtin types `int', `string', `character' and `float' can be
> +%	used to automatically generate DTDs.  This list may be extended in the
> +%	future.
>  %
>  % The generated DTD is also a good reference when creating a stylesheet as
>  % it contains comments describing the mapping from functors to elements.
> @@ -57,17 +66,10 @@
>  :- module term_to_xml.
>  :- interface.
>
> -:- import_module io, int, deconstruct, std_util.
> +:- import_module io, int, deconstruct, std_util, list.
>
>  %-----------------------------------------------------------------------------%
>
> -:- type maybe_stylesheet
> -	--->	with_stylesheet(
> -			stylesheet_type	:: string,
> -			stylesheet_href	:: string
> -		)
> -	;	no_stylesheet.
> -
>  	% Values of this type specify the DOCTYPE of an XML document when
>  	% the DOCTYPE is defined by an external DTD.
>  	%
> @@ -80,177 +82,349 @@
>  	% a generated XML document and if so how.
>  	%
>  :- type maybe_dtd
> -			% Embed the entire DTD in the document.
> +			% Generate and embed the entire DTD in the document.
>  	--->	embed
>  			% Included a reference to an external DTD.
>  	;	external(doctype)
>  			% Do not include any DOCTYPE information.
>  	;	no_dtd.
>
> +	% Values of this type indicate whether a stylesheet reference should be
> +	% included in a generated XML document.
> +:- type maybe_stylesheet
> +	--->	with_stylesheet(
> +			stylesheet_type	:: string, % For example "text/xsl"
> +			stylesheet_href	:: string
> +		)
> +	;	no_stylesheet.
> +
>  	% Values of this type indicate whether a DTD was successfully
>  	% generated or not.  A DTD cannot be generated for a type with more
>  	% than one top-level functor since only one root element can be
> -	% specified by a DTD.
> +	% specified by a DTD.  A DTD also cannot be generated for a
> +	% type where the mapping from functors of the type to
> +	% elements is not unique (since then the legal children DTD rules
> +	% cannot be expressed properly).
>  	%
since then the DTD rules for legal children cannot be expressed properly


>  :- type dtd_generation_result
>  	--->	ok
> -	;	multiple_functors_for_root.
> -
> -	% write_xml_doc(Term, MaybeStyleSheet, MaybeDTD, DTDResult, !IO).
> -	% Write Term to the current output stream as an XML document.
> +			% The root type is a discriminated union with
> +			% multiple functors.
> +			%
> +	;	multiple_functors_for_root
> +
> +			% The functor-to-element mapping maps different
> +			% functors to the same element.  The duplicate element
> +			% and a list of types whose functors map to that
> +			% element is given.
> +			%
> +	;	duplicate_elements(
> +			duplicate_element	:: string,
> +			duplicate_types		:: list(type_desc)
> +		)
> +	;
> +			% At the moment we only support generation of DTDs for
> +			% types made up of discriminated unions, arrays,
> +			% strings, ints, characters and floats.
> +			%
> +		unsupported_dtd_type(type_desc).
> +
> +	% Values of this type specify what mapping from functors to elements
s/what/which/ or s/what/the/

> +	% to use when generating XML.  The role of a mapping is two fold:
s/two fold/twofold/

> +	%	1. To map functors to elements, and
> +	%	2. To map functors to a set of attributes that should be
> +	%	set for the corresponding element.
> +	%
> +	% We provide two predefined mappings:
> +	%
> +	%	1. simple: The functors `[]', `[|]' and `{}' are mapped to the
> +	%	elements `List', `Nil' and `Tuple' respectively.  Arrays are
> +	%	assigned the `Array' element.  The builtin types are assigned
> +	% 	the elements `Int', `String', `Float' and `Char'.  All other
> +	%	functors are assigned elements with the same name as the
> +	%	functor provided the funtor name is well formed and does
> +	% 	not start with a capital letter.  Otherwise a mangled
> +	%	version of the functor name is used.
> +	%
> +	%	All elements except `Int', `String', `Float' and `Char'
> +	%	will have their `functor', `arity', `type' and `field' (if
> +	%	there is a field name) attrinutes set.  `Int', `String',
> +	%	`Float' and `Char' elements will just have their `type' and
> +	%	possibly their `field' attributes set.
> +	%
> +	%	The `simple' mapping is designed to be easy to read and use,
> +	%	but may result in the same element being assigned to different
> +	%	functors.
> +	%
> +	%	2. unique: Here we use the same mapping as `simple' except
> +	%	we append the fuctor arity for discriminated unions and
> +	%	a mangled version of the type name for every element.  The same
> +	%	attributes as the `simple' scheme are provided.  The advantage
> +	%	of this scheme is that it maps each functor to a unique
> +	%	element.  This means that it will always be possible to
> +	%	generate a DTD using this mapping so long as there is only
> +	%	one top level functor and no unsupported types can appear in
> +	%	terms of the type.
> +	%
> +	% A custom mapping can be provided using the `custom' functor.  See the
> +	% documentation for the element_pred type below for more information.
> +	%
> +:- type element_mapping
> +	--->	simple
> +	;	unique
> +	;	custom(element_pred).
> +
> +:- inst element_mapping
> +	--->	simple
> +	;	unique
> +	;	custom(element_pred).
> +
> +	% write_xml_doc(Term, ElementMapping, MaybeStyleSheet, MaybeDTD,
> +	% 	DTDResult, !IO).
> +	% Write Term to the current output stream as an XML document using
> +	% ElementMapping as the scheme to map functors to elements.
>  	% MaybeStyleSheet and MaybeDTD specify whether or not a stylesheet
>  	% reference and/or a DTD should be included.  Any non-canonical terms
> -	% will be canonicalized.  If an embedded DTD was requested and the type
> -	% has more than one top level functor then multiple_functors_for_root
> -	% will be returned in DTDResult and nothing will be written.
> +	% will be canonicalized.  If an embedded DTD is requested, but it is
> +	% not possible to generated a DTD for Term using ElementMapping, then a
s/generated/generate/

> +	% value other than `ok' is returned in DTDResult and nothing is written
> +	% out.  See the documentatin of the dtd_generation_result type for more
s/documentatin/documentation/

> +	% information of DTDResult when it is not `ok'.
>  	%
s/of/about/?  That last sentence doesn't make a great deal of sense
as written.

> -:- pred write_xml_doc(T::in, maybe_stylesheet::in, maybe_dtd::in,
> +:- pred write_xml_doc(T::in, element_mapping::in(element_mapping),
> +	maybe_stylesheet::in, maybe_dtd::in,
>  	dtd_generation_result::out, io::di, io::uo) is det.
>
> -	% write_xml_doc(Stream, Term, MaybeStyleSheet, MaybeDTD, DTDResult,
> -	%	!IO).
> -	% Same as write_xml_doc/5 except write the XML doc to the given
> +	% write_xml_doc(Stream, Term, ElementMapping, MaybeStyleSheet,
> +	%	MaybeDTD, DTDResult, !IO).
> +	% Same as write_xml_doc/7 except write the XML doc to the given
>  	% output stream.
>  	%
> -:- pred write_xml_doc(io.output_stream::in, T::in, maybe_stylesheet::in,
> +:- pred write_xml_doc(io.output_stream::in, T::in,
> +	element_mapping::in(element_mapping), maybe_stylesheet::in,
>  	maybe_dtd::in, dtd_generation_result::out, io::di, io::uo) is det.
>
> -	% write_xml_doc_cc(Term, MaybeStyleSheet, MaybeDTD, DTDResult, !IO).
> -	% Write Term to the current output stream as an XML document.
> +	% write_xml_doc_cc(Term, ElementMapping, MaybeStyleSheet, MaybeDTD,
> +	%	DTDResult, !IO).
> +	% Write Term to the current output stream as an XML document using
> +	% ElementMapping as the scheme to map functors to elements.
>  	% MaybeStyleSheet and MaybeDTD specify whether or not a stylesheet
>  	% reference and/or a DTD should be included.  Any non-canonical terms
> -	% will be be written out in full. If an embedded DTD was requested and
> -	% the type has more than one top level functor then
> -	% multiple_functors_for_root will be returned in DTDResult and nothing
> -	% will be written.
> -	%
> -:- pred write_xml_doc_cc(T::in, maybe_stylesheet::in, maybe_dtd::in,
> -	dtd_generation_result::out, io::di, io::uo) is cc_multi.
> -
> -	% write_xml_doc_cc(Stream, Term, MaybeStyleSheet, MaybeDTD, DTDResult,
> -	%	!IO).
> -	% Same as write_xml_doc/5 except write the XML doc to the given
> +	% will be be written out in full.  If an embedded DTD is requested, but
> +	% it is not possible to generated a DTD for Term using ElementMapping,
> +	% then a value other than `ok' is returned in DTDResult and nothing is
> +	% written out.  See the documentatin of the dtd_generation_result type
s/documentatin/documentation/

More later...

Cheers,
Julien.
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list