From 84adefa331c4159d432d22840663c38f155cd4c1 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Fri, 20 Nov 2009 14:54:40 +0000 Subject: The R13B03 release. --- lib/xmerl/doc/src/Makefile | 181 ++++++++ lib/xmerl/doc/src/book.xml | 49 +++ lib/xmerl/doc/src/fascicules.xml | 18 + lib/xmerl/doc/src/make.dep | 24 ++ lib/xmerl/doc/src/motorcycles.txt | 26 ++ lib/xmerl/doc/src/motorcycles2.txt | 80 ++++ lib/xmerl/doc/src/motorcycles2html.erl | 108 +++++ lib/xmerl/doc/src/motorcycles_dtd.txt | 18 + lib/xmerl/doc/src/new_motorcycles.txt | 24 ++ lib/xmerl/doc/src/new_motorcycles2.txt | 35 ++ lib/xmerl/doc/src/notes.xml | 680 +++++++++++++++++++++++++++++++ lib/xmerl/doc/src/notes_history.xml | 48 +++ lib/xmerl/doc/src/part.xml | 38 ++ lib/xmerl/doc/src/part_notes.xml | 39 ++ lib/xmerl/doc/src/people.txt | 21 + lib/xmerl/doc/src/people2.txt | 39 ++ lib/xmerl/doc/src/ref_man.xml | 43 ++ lib/xmerl/doc/src/result_export.html | 25 ++ lib/xmerl/doc/src/result_xs.html | 83 ++++ lib/xmerl/doc/src/xmerl_examples.html | 408 +++++++++++++++++++ lib/xmerl/doc/src/xmerl_sax_parser.xml | 426 +++++++++++++++++++ lib/xmerl/doc/src/xmerl_ug.xmlsrc | 490 ++++++++++++++++++++++ lib/xmerl/doc/src/xmerl_xs_examples.html | 291 +++++++++++++ 23 files changed, 3194 insertions(+) create mode 100644 lib/xmerl/doc/src/Makefile create mode 100644 lib/xmerl/doc/src/book.xml create mode 100644 lib/xmerl/doc/src/fascicules.xml create mode 100644 lib/xmerl/doc/src/make.dep create mode 100644 lib/xmerl/doc/src/motorcycles.txt create mode 100644 lib/xmerl/doc/src/motorcycles2.txt create mode 100644 lib/xmerl/doc/src/motorcycles2html.erl create mode 100644 lib/xmerl/doc/src/motorcycles_dtd.txt create mode 100644 lib/xmerl/doc/src/new_motorcycles.txt create mode 100644 lib/xmerl/doc/src/new_motorcycles2.txt create mode 100644 lib/xmerl/doc/src/notes.xml create mode 100644 lib/xmerl/doc/src/notes_history.xml create mode 100644 lib/xmerl/doc/src/part.xml create mode 100755 lib/xmerl/doc/src/part_notes.xml create mode 100644 lib/xmerl/doc/src/people.txt create mode 100644 lib/xmerl/doc/src/people2.txt create mode 100644 lib/xmerl/doc/src/ref_man.xml create mode 100644 lib/xmerl/doc/src/result_export.html create mode 100644 lib/xmerl/doc/src/result_xs.html create mode 100644 lib/xmerl/doc/src/xmerl_examples.html create mode 100644 lib/xmerl/doc/src/xmerl_sax_parser.xml create mode 100644 lib/xmerl/doc/src/xmerl_ug.xmlsrc create mode 100644 lib/xmerl/doc/src/xmerl_xs_examples.html (limited to 'lib/xmerl/doc/src') diff --git a/lib/xmerl/doc/src/Makefile b/lib/xmerl/doc/src/Makefile new file mode 100644 index 0000000000..e26e77eb96 --- /dev/null +++ b/lib/xmerl/doc/src/Makefile @@ -0,0 +1,181 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2004-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../../vsn.mk +VSN=$(XMERL_VSN) +APPLICATION=xmerl + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN) + +# ---------------------------------------------------- +# Help application directory specification +# ---------------------------------------------------- + +EDOC_DIR = $(ERL_TOP)/lib/edoc +SYNTAX_TOOLS_DIR = $(ERL_TOP)/lib/syntax_tools + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +XMERL_DIR = $(ERL_TOP)/lib/$(APPLICATION)/src + +XMERL_MODULES = \ + xmerl_scan \ + xmerl \ + xmerl_xs \ + xmerl_eventp \ + xmerl_xpath \ + xmerl_xsd + + +XML_APPLICATION_FILES = ref_man.xml +XMERL_XML_FILES = $(XMERL_MODULES:=.xml) + +XML_REF3_FILES = $(XMERL_XML_FILES) \ + xmerl_sax_parser.xml + +XML_PART_FILES = \ + part.xml \ + part_notes.xml + +XML_REF6_FILES = + +XML_CHAPTER_FILES = \ + xmerl_ug.xml \ + notes.xml + + +HTML_EXAMPLE_FILES = \ + xmerl_examples.html \ + xmerl_xs_examples.html + +HTML_STYLESHEET_FILES = \ + ../stylesheet.css + +BOOK_FILES = book.xml + +XML_HTML_FILES = \ + notes_history.xml + +EXAMPLE_FILES = people2.txt people.txt motorcycles.txt motorcycles_dtd.txt \ + new_motorcycles.txt new_motorcycles2.txt result_export.html \ + motorcycles2.txt result_xs.html motorcycles2html.erl + +XML_FILES= \ + $(BOOK_FILES) $(XML_CHAPTER_FILES) \ + $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_APPLICATION_FILES) + +# ---------------------------------------------------- +INFO_FILE = ../../info + +HTML_FILES = $(XML_REF_MAN:%.xml=$(HTMLDIR)/%.html) \ + $(XML_HTML_FILES:%.xml=$(HTMLDIR)/%.html) \ + $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html) + + +MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3) +MAN6_FILES = $(XML_REF6_FILES:%_app.xml=$(MAN6DIR)/%.6) + +HTML_REF_MAN_FILE = $(HTMLDIR)/index.html + +TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf + + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +XML_FLAGS += +DVIPS_FLAGS += + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- +$(HTMLDIR)/%.gif: %.gif + $(INSTALL_DATA) $< $@ + +docs: pdf html man + +$(TOP_PDF_FILE): $(XML_FILES) + +pdf: $(TOP_PDF_FILE) + +html: gifs $(HTML_REF_MAN_FILE) + +$(XMERL_XML_FILES): + docb_gen $(XMERL_DIR)/$(@:%.xml=%.erl) + +man: $(MAN3_FILES) $(MAN6_FILES) + +gifs: $(GIF_FILES:%=$(HTMLDIR)/%) + +xml: $(XMERL_XML_FILES) + +debug opt: + +clean clean_docs: + rm -rf $(HTMLDIR)/* + rm -f $(MAN3DIR)/* + rm -f $(MAN6DIR)/* + rm -f $(XMERL_XML_FILES) + rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) + rm -f errs core *~ + + +info: + @echo "XML_PART_FILES: $(XML_PART_FILES)" + @echo "XML_APPLICATION_FILES: $(XML_APPLICATION_FILES)" + @echo "XMERL_XML_FILES: $(XMERL_XML_FILES)" + @echo "XMERL_MODULES: $(XMERL_MODULES)" + @echo "HTML_FILES: $(HTML_FILES)" + @echo "HTMLDIR: $(HTMLDIR)" + @echo "DEFAULT_GIF_FILES: $(DEFAULT_GIF_FILES)" + @echo "DEFAULT_HTML_FILES: $(DEFAULT_HTML_FILES)" + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_docs_spec: docs + $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf + $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf + $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DATA) $(HTMLDIR)/* \ + $(RELSYSDIR)/doc/html + $(INSTALL_DATA) $(EXAMPLE_FILES) $(HTML_EXAMPLE_FILES) $(HTML_STYLESHEET_FILES) $(RELSYSDIR)/doc/html + $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) + $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 + $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + +release_spec: + + + +release_tests_spec: + + + diff --git a/lib/xmerl/doc/src/book.xml b/lib/xmerl/doc/src/book.xml new file mode 100644 index 0000000000..d46d37cf85 --- /dev/null +++ b/lib/xmerl/doc/src/book.xml @@ -0,0 +1,49 @@ + + + + +
+ + 20042009 + Ericsson AB. All Rights Reserved. + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + + + xmerl + Bertil Karlsson + + 2004-06-02 + 0.9 + book.xml +
+ + + xmerl + + + + + + + + + + + + + + +
+ diff --git a/lib/xmerl/doc/src/fascicules.xml b/lib/xmerl/doc/src/fascicules.xml new file mode 100644 index 0000000000..0678195e07 --- /dev/null +++ b/lib/xmerl/doc/src/fascicules.xml @@ -0,0 +1,18 @@ + + + + + + User's Guide + + + Reference Manual + + + Release Notes + + + Off-Print + + + diff --git a/lib/xmerl/doc/src/make.dep b/lib/xmerl/doc/src/make.dep new file mode 100644 index 0000000000..9c303fc41c --- /dev/null +++ b/lib/xmerl/doc/src/make.dep @@ -0,0 +1,24 @@ +# ---------------------------------------------------- +# >>>> Do not edit this file <<<< +# This file was automaticly generated by +# /home/otp/bin/docdepend +# ---------------------------------------------------- + + +# ---------------------------------------------------- +# TeX files that the DVI file depend on +# ---------------------------------------------------- + +book.dvi: book.tex part.tex ref_man.tex xmerl.tex xmerl_eventp.tex \ + xmerl_scan.tex xmerl_ug.tex xmerl_xpath.tex \ + xmerl_xs.tex xmerl_xsd.tex xmerl_sax_parser.tex + +# ---------------------------------------------------- +# Source inlined when transforming from source to LaTeX +# ---------------------------------------------------- + +book.tex: ref_man.xml + +xmerl_ug.tex: motorcycles.txt motorcycles2html.erl motorcycles_dtd.txt \ + new_motorcycles.txt new_motorcycles2.txt + diff --git a/lib/xmerl/doc/src/motorcycles.txt b/lib/xmerl/doc/src/motorcycles.txt new file mode 100644 index 0000000000..5aab475747 --- /dev/null +++ b/lib/xmerl/doc/src/motorcycles.txt @@ -0,0 +1,26 @@ + + + + + + Suzuki + Suzuki VL 1500 + Intruder + + V-engine, 2-cylinders, 1500 cc + custom + cardan + Sissy bar, luggage carrier,V&H exhaust pipes + + 2004.08.25 + + + Yamaha + XJ 400 + + 4 cylinder, 400 cc + alround + chain + Good shape! + + diff --git a/lib/xmerl/doc/src/motorcycles2.txt b/lib/xmerl/doc/src/motorcycles2.txt new file mode 100644 index 0000000000..767cdd5996 --- /dev/null +++ b/lib/xmerl/doc/src/motorcycles2.txt @@ -0,0 +1,80 @@ + + + + + + Suzuki + Suzuki VL 1500 + Intruder + + V-engine, 2-cylinders, 1500 cc + custom + cardan + Sissy bar, luggage carrier,V&H exhaust pipes + + 2004.08.25 + + + Suzuki + Suzuki GSX 750 + + 4 cylinders, 750 cc + alround + chain + + 2004.05.22 + + + Suzuki + Suzuki GSX 750 + + 4 cylinders, 750 cc + alround + chain + + 2003.09.27 + + + Suzuki + Suzuki VS 1400 + Intruder + + V-engine, 2 cylinders, 1400 cc + custom + cardan + + 2004.08.23 + + + Yamaha + XJ 400 + + 4 cylinder, 400 cc + alround + chain + Good shape! + + + + Yamaha + XTZ 750 + Super Tenere + + 2 cylinders, 750 cc + offroad + chain + Top box + + 2003.02.13 + + + Harley Davidsson + HD FLSTCi + Heritage Softail Classic + + V-engine, 2 cylinders, 1500 cc + custom + belt + + 2004.04.04 + diff --git a/lib/xmerl/doc/src/motorcycles2html.erl b/lib/xmerl/doc/src/motorcycles2html.erl new file mode 100644 index 0000000000..dfbd19e359 --- /dev/null +++ b/lib/xmerl/doc/src/motorcycles2html.erl @@ -0,0 +1,108 @@ +%%%------------------------------------------------------------------- +%%% File : motorcycles2html.erl +%%% Author : Bertil Karlsson +%%% Description : +%%% +%%% Created : 2 Sep 2004 by Bertil Karlsson +%%%------------------------------------------------------------------- +-module(motorcycles2html). + +-include("xmerl.hrl"). + +-import(xmerl_xs, + [ xslapply/2, value_of/1, select/2, built_in_rules/2 ]). + +-export([process_xml/1,process_to_file/2,process_to_file/1]). + +process_xml(Doc) -> + template(Doc). + +process_to_file(FileName) -> + process_to_file(FileName,'motorcycles.xml'). + +process_to_file(FileName,XMLDoc) -> + case file:open(FileName,[write]) of + {ok,IOF} -> + {XMLContent,_} = xmerl_scan:file(XMLDoc), + TransformedXML=process_xml(XMLContent), + io:format(IOF,"~s",[TransformedXML]), + file:close(IOF); + {error,Reason} -> + io:format("could not open file due to ~p.~n",[Reason]) + end. + +%%% templates +template(E = #xmlElement{name='motorcycles'}) -> + [ "\nmotorcycles\n\n", + "\n", + "

Used Motorcycles

\n", + "
    \n", + remove_duplicates(value_of(select("bike/name/manufacturer",E))), + "\n
\n", + sort_by_manufacturer(xslapply(fun template/1, E)), + "\n", + "\n"]; +template(E = #xmlElement{name='bike'}) -> + {value_of(select("name/manufacturer",E)),["
",xslapply(fun template/1,select("name",E)),"
", + "
    \n", + "
  • Manufacturing year: ",xslapply(fun template/1,select("@year",E)),"
  • \n", + "
  • Color: ",xslapply(fun template/1,select("@color",E)),"
  • \n", + "
  • Shape : ",xslapply(fun template/1,select("@condition",E)),"
  • \n", + "
\n"]}; +template(E) -> built_in_rules(fun template/1, E). + + +%%%%%%%%%%% helper routines + +%% sorts on the bike name element, unwraps the bike information and +%% inserts a line feed and indentation on each bike element. +sort_by_manufacturer(L) -> + Tuples=[X1||X1={H,T} <- L], + SortedTS = lists:keysort(1,Tuples), + InsertRefName_UnWrap= + fun([{[Name],V}|Rest],Name,F)-> + [V|F(Rest,Name,F)]; + ([{[Name],V}|Rest],PreviousName,F) -> + [[""],V|F(Rest,Name,F)]; + ([],_,_) -> [] + end, + SortedRefed=InsertRefName_UnWrap(SortedTS,no_name,InsertRefName_UnWrap), +% SortedTs=[Y||{X,Y}<-lists:keysort(1,Tuples)], + WS = "\n ", + Fun=fun([H|T],Acc,F)-> + F(T,[H,WS|Acc],F); + ([],Acc,F)-> + lists:reverse([WS|Acc]) + end, + if length(SortedRefed) > 0 -> + Fun(SortedRefed,[],Fun); + true -> [] + end. + + +%% removes all but the first of an element in L and inserts a html +%% reference for each list element. +remove_duplicates(L) -> + remove_duplicates(L,[]). + +remove_duplicates([],Acc) -> + make_ref(lists:sort(lists:reverse(Acc))); +remove_duplicates([A|L],Acc) -> + case lists:delete(A,L) of + L -> + remove_duplicates(L,[A|Acc]); + L1 -> + remove_duplicates([A|L1],[Acc]) + end. + +make_ref([]) -> []; +make_ref([H]) when atom(H) -> + ""; +make_ref([H]) when list(H) -> + ""; +make_ref([H|T]) when atom(H) -> + ["" + |make_ref(T)]; +make_ref([H|T]) when list(H) -> + [""|make_ref(T)]. + diff --git a/lib/xmerl/doc/src/motorcycles_dtd.txt b/lib/xmerl/doc/src/motorcycles_dtd.txt new file mode 100644 index 0000000000..bab0d563f0 --- /dev/null +++ b/lib/xmerl/doc/src/motorcycles_dtd.txt @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/lib/xmerl/doc/src/new_motorcycles.txt b/lib/xmerl/doc/src/new_motorcycles.txt new file mode 100644 index 0000000000..6fc1dd836c --- /dev/null +++ b/lib/xmerl/doc/src/new_motorcycles.txt @@ -0,0 +1,24 @@ + + + + Suzuki + Suzuki VL 1500 + Intruder + + V-engine, 2-cylinders, 1500 cc + custom + cardan + Sissy bar, luggage carrier,V&H exhaust pipes + + 2004.08.25 + + + Yamaha + XJ 400 + + 4 cylinder, 400 cc + alround + chain + Good shape! + +Harley DavidssonXL1200CSportsterV-engine, 2-cylinders, 1200 cccustombelt diff --git a/lib/xmerl/doc/src/new_motorcycles2.txt b/lib/xmerl/doc/src/new_motorcycles2.txt new file mode 100644 index 0000000000..445f6c4035 --- /dev/null +++ b/lib/xmerl/doc/src/new_motorcycles2.txt @@ -0,0 +1,35 @@ + + + + + + Suzuki + Suzuki VL 1500 + Intruder + + V-engine, 2-cylinders, 1500 cc + custom + cardan + Sissy bar, luggage carrier,V&H exhaust pipes + + 2004.08.25 + + + Yamaha + XJ 400 + + 4 cylinder, 400 cc + alround + chain + Good shape! + + + + Harley Davidsson + XL1200C + Sportster + V-engine, 2-cylinders, 1200 cc + custom + belt + + diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml new file mode 100644 index 0000000000..115c81a806 --- /dev/null +++ b/lib/xmerl/doc/src/notes.xml @@ -0,0 +1,680 @@ + + + + +
+ + 20042009 + Ericsson AB. All Rights Reserved. + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + + + Xmerl Release Notes + otp_appnotes + nil + nil + nil + notes.xml +
+

This document describes the changes made to the Xmerl application.

+ + + + +
Xmerl 1.2.3 + +
Fixed Bugs and Malfunctions + + +

+ A continuation clause of parse_reference/3 had + it's parameters in wrong order.

+

+ Own Id: OTP-8251 Aux Id: seq11429

+
+
+
+ + +
Improvements and New Features + + +

+ A new option to turn off the parsing of an external DTD + is added to xmerl_sax_parser:file/2 and + xmerl_sax_parser:stream/2 + (skip_external_dtd).

+

+ Own Id: OTP-8252 Aux Id: seq11432

+
+ +

+ The documentation is now built with open source tools + (xsltproc and fop) that exists on most platforms. One + visible change is that the frames are removed.

+

+ Own Id: OTP-8253

+
+
+
+ +
+ +
Xmerl 1.2.2 + +
Fixed Bugs and Malfunctions + + +

+ xmerl_sax_parse:stream/2 failed with + {fatal_error,_, "Continuation function undefined, and + more data needed",_,_} when no continuation function + was defined even though it was a complete document as + input.

+

+ Own Id: OTP-8213

+
+ +

+ The namespace URI supplied on unprefixed attributes in + startElement tuples is the same as the URI for the + default namespace. According to the standard the + namespace for an unprefixed attribute should always has + no value.

+

+ Own Id: OTP-8214

+
+
+
+ +
+ +
Xmerl 1.2.1 + +
Fixed Bugs and Malfunctions + + +

+ xmerl/include/xmerl.hrl contained internal debug + macros (dbg/2 and DBG/0) which now is moved + to xmerl_internal.hrl. +

+

+ Own Id: OTP-8084 +

+
+ +

+ The function xmerl_uri:parse/1 couldn't handle FTP + URIs containing username and password. The default FTP + port constant was also wrong. (Thanks to Steve Vinoski) +

+

+ Own Id: OTP-8156 +

+
+
+
+ + +
Improvements and New Features + + +

+ The SAX parser couldn't handle consecutive documents on + the same stream. The return values are now changed so + they return a rest value instead of giving an error about + "erranous information after the end tag". +

+

+ This means that + the functions file/2 and stream/2 now + returns {ok, EventState, Rest} when the parsing is + correct. The rest can then be used as input to a new call + to xmerl_sax_parse:stream/2. If one know that it's + just one document the rest value in the result tuple can + be matched against <<>> or [] + depending on if the input is in binary form or not. +

+

+ Own Id: OTP-8153 Aux Id: seq11388 +

+
+
+
+ +
+ + +
Xmerl 1.2 +
Improvements and New Features +

+ In xmerl-1.2 we have added the first Beta version of the new + SAX parser (module: xmerl_sax_parser), it supports XML 1.0. + We call it Beta due to that the validation part is not ready yet and that the + parser still has some known limitations (mostly in the DTD area). +

+

+ Known limitations: +

+ + the external DTD in the DOCTYPE declaration is handled but other external entities are not supported. + the general entity values are just checked in the structure after replacement. + + parsed entities are supported on markup declaration level (e.g. partly replacement of markup + declaration with PEReference is not supported). + + conditionalSect in external DTD's are not supported. + recursive loops in entity declarations are not detected. + +

+ The version is increased from 1.1.12 to 1.2 is due to that the new parser + is dependent on the Unicode support that was added in OTP R13B. The old xmerl + functionality is not changed. +

+

+ Own Id: OTP-6635 +

+
+
+ +
Xmerl 1.1.12 + +
Improvements and New Features + + +

+ Updated copyright notice in source files

+

+ Own Id: OTP-7847

+
+
+
+ +
+ +
Xmerl 1.1.11 + +
Fixed Bugs and Malfunctions + + +

+ An empty element with a complexType and simpleContent was + not properly validated. This error is now corrected.

+

+ Own Id: OTP-7736

+
+
+
+ +
+ +
Xmerl 1.1.10 + +
Fixed Bugs and Malfunctions + + +

+ Changed the examples in Customization Functions Tutorial + to correct Erlang code. +

+

+ Own Id: OTP-6053 +

+
+ +

+ Some XPath errors solved, typo in compare function '!=', + error in id() function.

+

+ Own Id: OTP-6792 Aux Id: seq10570

+
+ +

+ The XPath function contains() now implemented. See + XPath 1.0 section 4.2.

+

+ Own Id: OTP-6873

+
+ +

+ Fixed that xmerl_xsd:process_schema/2 with {xsdbase, Dirname} failed with enoent + and a number of inor documentation bugs in xmerl_xsd reference manual. +

+

+ Own Id: OTP-7165 +

+
+ +

+ Fixed xmerl_scan's problem with numeric character references + followed by UTF-8 characters in the contents. +

+

+ Own Id: OTP-7430 +

+
+ +

+ Fixed an incorrect guard for xmerl_scan:to_ucs/2. +

+

+ Own Id: OTP-7473 +

+
+ +

+ Some bug corrections of xmerl XPath implementation, most + provided by Matthew Dempsky.

+

+ Own Id: OTP-7496

+
+ +

+ Now with string() and name() all XPath + functions are implemented. The string representation of + QName by name() is "{Namespace URI}local-name".

+

+ Own Id: OTP-7510

+
+ +
+
+ +
+ + +
Xmerl 1.1.9 + +
Fixed Bugs and Malfunctions + + +

+ A number of minor scanner faults have got more clear error messages. +

+

+ Own Id: OTP-5998, Aux Id: seq9803 +

+
+ +

+ An example error in the Xmerl Users Guide is corrected. +

+

+ Own Id: OTP-6947 +

+
+ +

+ When xmerl_xsd:validate was executed the schema table in the state + was deleted and next execution would fail. This is now corrected. +

+

+ Own Id: OTP-7288 +

+
+
+
+ +
+ + +
Xmerl 1.1.8 + +
Fixed Bugs and Malfunctions + + +

+ A Kleene Closure child in a sequence consumed all + following children. This problem has been fixed.

+

+ Own Id: OTP-7211

+
+ +

+ Now validating xhtml1-transitional.dtd. A certain + contentspec with a succeeding choice, that didn't match + all content, followed by other child elements caused a + failure. This is now corrected.

+

+ Own Id: OTP-7214

+
+
+
+ +
+ +
Xmerl 1.1.7 + +
Improvements and New Features + + +

+ xmerl's schema validation now takes default facets into + account

+

+ Own Id: OTP-7190

+
+
+
+ +
+ +
Xmerl 1.1.6 + +
Fixed Bugs and Malfunctions + + +

+ Parsing XML with option {validation,schema} is now + corrected.

+

+ Own Id: OTP-6773

+
+ +

+ union type is now supported

+

+ Own Id: OTP-6877 Aux Id: seq10755

+
+ +

+ Now xmerl validates as expected when a sequence has a + present group member and a following element.

+

+ Own Id: OTP-6910

+
+
+
+ +
+ +
+ Xmerl 1.1.5 + +
+ Fixed Bugs and Malfunctions + + +

The head of a substitutionGroup may have type anyType and + thus allow members of any type. This was an oversight, but is + now corrected.

+

Own Id: OTP-6720

+
+ +

A recursive group reference in a redefine refers to the + definition in the redefined schema. See 4.2.2 in + XMLSchema part1 "Schema Representation Constraint: + Individual Component Redefinition" bullet 2.

+

Own Id: OTP-6739

+
+ +

Solved some content model problems, for instance in some + cases failed when more than one choice.

+

Own Id: OTP-6752

+
+
+
+
+ +
+ Xmerl 1.1.4 + +
+ Improvements and New Features + + +

An additional format is possible for the simple syntax: + {Fun, State}. The fun should retrieve the + replacement in simple syntax format. The semantics of + fun: fun(State) -> code that creates replacement, then returns {SimpleSyntax,NewState} | done

+

Own Id: OTP-6679

+
+
+
+
+ +
+ Xmerl 1.1.3 + +
+ Improvements and New Features + + +

Memory consumption decreased: moved transforming from + utf-8 to unicode from an extra pass of the document to + the occasion when a character is parsed. Removed use of + lists:subtract. Those changes also speeds up parsing in + some scenarios.

+

Own Id: OTP-6599 Aux Id: seq10552

+
+
+
+
+ +
+ Xmerl 1.1.2 + +
+ Fixed Bugs and Malfunctions + + +

Schema processor reprocessed schemas that already were + processed, using process_schemas on a system of schemas + with circular dependencies.

+

Own Id: OTP-6460 Aux Id: seq10564

+
+
+
+ +
+ Improvements and New Features + + +

Dialyzer warnings now removed, i.e. dead code have been + removed.

+

Own Id: OTP-6507

+
+
+
+
+ +
+ Xmerl 1.1.1 + +
+ Fixed Bugs and Malfunctions + + +

Bug in xmerl removed so that simple syntax element + content is exported correctly.

+

Own Id: OTP-6402 Aux Id: OTP-6099

+
+
+
+
+ +
+ Xmerl 1.1 + +
+ Fixed Bugs and Malfunctions + + +

Xmerl failed to parse and export with the sax_file + front-end. Therefore hook function calls were added in the + parser and handling of text content were changed.

+

Own Id: OTP-6043

+
+ +

Bug in xmerl removed so that simple syntax element + content is exported correctly.

+

Own Id: OTP-6099

+
+
+
+ +
+ Improvements and New Features + + +

xmerl now supports XMLSchema validation. Documentation in + reference manual for xmerl. The release of XMLSchema + validation should be considered as a beta release. The + user interface may still be adjusted in a coming + release. Opinions and evaluations are welcome.

+

Own Id: OTP-6401

+
+
+
+
+ +
+ xmerl 1.0.5 + +
+ Fixed Bugs and Malfunctions + + +

Code that caused compiler warnings has been reviewed.

+
+
+
+
+ +
+ xmerl 1.0.4 + +
+ Fixed Bugs and Malfunctions + + +

xmerl behaved strange parsing a XML-document with a + copyright sign in a comment.

+

Own Id: OTP-5599

+
+ +

Line count for error messages in DTD improved, still + problem because of ENTITY expansions. Didn't delete + digraphs after recursion test. Now correctly parsing of + declaration separators [28a-b].

+

Own Id: OTP-5718

+
+ +

Failed to validate a XML file with a content spec that + had a choice of which one element was a sequence with + optional elements, and all elements of that sequence were + missing

+

Own Id: OTP-5734

+
+ +

Location paths for document root and attributes is now + working as expected.

+

Own Id: OTP-5895

+
+ +

Now has the last() predicate in the XPATH modules the + properties specified in ch 2.4 in the XPATH spec, i.e. if + last() evaluates to a number other than the context + position it is false, otherwise true.

+

Own Id: OTP-5902

+
+ +

The location path of a single wildcard now only selects + element nodes.

+

Own Id: OTP-5905

+
+
+
+
+ +
+ Xmerl 1.0.3 + +
+ Fixed Bugs and Malfunctions + + +

Removed call of undefined function in xmerl_lib.

+

Own Id: OTP-5587

+
+
+
+
+ +
+ Xmerl 1.0.2 + +
+ Fixed Bugs and Malfunctions + + +

Better identification of errors in xml code.

+

Own Id: OTP-5498 Aux Id: seq9803

+
+ +

Some minor bugs fixed.

+

Own Id: OTP-5500

+
+ +

Parser failed on PE reference as EnumeratedType AttType, + now corrected.

+

Own Id: OTP-5531

+
+
+
+
+ +
+ Xmerl 1.0.1 + +
+ Fixed Bugs and Malfunctions + + +

Fixed bug in xmerl_xpath. Xpath expressions that select + nodes of type text() didn't work, like "context/text()", + "child::text()", "descendant::text()".

+

Own Id: OTP-5268 Aux Id: seq9656

+
+ +

Minor bugs fixed.

+

Own Id: OTP-5301

+
+
+
+ +
+ +
+ Xmerl 1.0 + +
+ Improvements and New Features + + +

The OTP release of xmerl 1.0 is mainly the same as + xmerl-0.20 of http://sowap.sourceforge.net/. It is + capable of parsing XML 1.0. There have only been minor + improvements: Some bugs that caused an unexpected crash + when parsing bad XML. Failure report that also tells + which file that caused an error.

+

Own Id: OTP-5174

+
+
+
+
+
+ diff --git a/lib/xmerl/doc/src/notes_history.xml b/lib/xmerl/doc/src/notes_history.xml new file mode 100644 index 0000000000..06d0cb3b40 --- /dev/null +++ b/lib/xmerl/doc/src/notes_history.xml @@ -0,0 +1,48 @@ + + + + +
+ + 2006 + 2007 + Ericsson AB, All Rights Reserved + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + The Initial Developer of the Original Code is Ericsson AB. + + + Xmerl Release Notes + Bertil Karlsson + + + + + 06-04-21 + + notes_history.sgml +
+

This document describes the changes made to the Xmerl system + from version to version. The intention of this document is to + list all incompatibilities as well as all enhancements and + bugfixes for every release of Xmerl. Each release of Xmerl + thus constitutes one section in this document. The title of each + section is the version number of Xmerl.

+ +
+ Xmerl before OTP +

The sorceforge location of the original user contribution

+
+
+ diff --git a/lib/xmerl/doc/src/part.xml b/lib/xmerl/doc/src/part.xml new file mode 100644 index 0000000000..8a544ad3b0 --- /dev/null +++ b/lib/xmerl/doc/src/part.xml @@ -0,0 +1,38 @@ + + + + +
+ + 20042009 + Ericsson AB. All Rights Reserved. + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + + + xmerl User's Guide + Bertil Karlsson + + 2004-06-02 + 0.9 + part.xml +
+ +

The xmerl application + contains modules with support for processing of xml files compliant to XML 1.0. +

+
+ +
+ diff --git a/lib/xmerl/doc/src/part_notes.xml b/lib/xmerl/doc/src/part_notes.xml new file mode 100755 index 0000000000..827ffd90e9 --- /dev/null +++ b/lib/xmerl/doc/src/part_notes.xml @@ -0,0 +1,39 @@ + + + + +
+ + 20042009 + Ericsson AB. All Rights Reserved. + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + + + Xmerl Release Notes + Bertil Karlsson + + >2004-12-15 + + part_notes.xml +
+ +

The Xmerl application + contains modules with support for processing of xml files compliant to XML 1.0.

+

There are also release notes for + older versions.

+
+ +
+ diff --git a/lib/xmerl/doc/src/people.txt b/lib/xmerl/doc/src/people.txt new file mode 100644 index 0000000000..7472d8d42c --- /dev/null +++ b/lib/xmerl/doc/src/people.txt @@ -0,0 +1,21 @@ + + + + + Alan + Turing + + computer scientist + mathematician + cryptographer + + + + Richard + P + Feynman + + physicist + Playing the bongos + + diff --git a/lib/xmerl/doc/src/people2.txt b/lib/xmerl/doc/src/people2.txt new file mode 100644 index 0000000000..156a692e21 --- /dev/null +++ b/lib/xmerl/doc/src/people2.txt @@ -0,0 +1,39 @@ + + + + + + + + + + + +]> + + + + + + Alan + Turing + + computer scientist + mathematician + cryptographer + + + + Richard + P + Feynman + + physicist + Playing the bongos + + diff --git a/lib/xmerl/doc/src/ref_man.xml b/lib/xmerl/doc/src/ref_man.xml new file mode 100644 index 0000000000..4b79d75d47 --- /dev/null +++ b/lib/xmerl/doc/src/ref_man.xml @@ -0,0 +1,43 @@ + + + + +
+ + 20042009 + Ericsson AB. All Rights Reserved. + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + + + xmerl Reference Manual + OTP Team + + 2004-06-02 + 1.0 + ref_man.xml +
+ +

The xmerl application + contains modules with support for processing of xml files compliant to XML 1.0.

+
+ + + + + + + +
+ diff --git a/lib/xmerl/doc/src/result_export.html b/lib/xmerl/doc/src/result_export.html new file mode 100644 index 0000000000..e727bc88f8 --- /dev/null +++ b/lib/xmerl/doc/src/result_export.html @@ -0,0 +1,25 @@ + + + + + Suzuki + Suzuki VL 1500 + Intruder + + V-engine, 2-cylinders, 1500 cc + custom + cardan + Sissy bar, luggage carrier,V&H exhaust pipes + + 2004.08.25 + + + Yamaha + XJ 400 + + 4 cylinder, 400 cc + alround + chain + Good shape! + + diff --git a/lib/xmerl/doc/src/result_xs.html b/lib/xmerl/doc/src/result_xs.html new file mode 100644 index 0000000000..9f5fb336dd --- /dev/null +++ b/lib/xmerl/doc/src/result_xs.html @@ -0,0 +1,83 @@ + +motorcycles + + +

Used Motorcycles

+ + + +
+ Harley Davidsson + HD FLSTCi + Heritage Softail Classic +
    +
  • Manufacturing year: 2001
  • +
  • Color: red
  • +
  • Shape :
  • +
+ +
+
+ Suzuki + Suzuki VL 1500 + Intruder +
    +
  • Manufacturing year: 2000
  • +
  • Color: black
  • +
  • Shape :
  • +
+ +
+ Suzuki + Suzuki GSX 750 +
    +
  • Manufacturing year: 1998
  • +
  • Color: yellow
  • +
  • Shape :
  • +
+ +
+ Suzuki + Suzuki GSX 750 +
    +
  • Manufacturing year: 1998
  • +
  • Color: silver metallic
  • +
  • Shape :
  • +
+ +
+ Suzuki + Suzuki VS 1400 + Intruder +
    +
  • Manufacturing year: 1999
  • +
  • Color: black and silver matallic
  • +
  • Shape :
  • +
+ +
+
+ Yamaha + XJ 400 +
    +
  • Manufacturing year: 1983
  • +
  • Color: read pearl
  • +
  • Shape :
  • +
+ +
+ Yamaha + XTZ 750 + Super Tenere +
    +
  • Manufacturing year: 1990
  • +
  • Color: blue and white
  • +
  • Shape : good
  • +
+ + + diff --git a/lib/xmerl/doc/src/xmerl_examples.html b/lib/xmerl/doc/src/xmerl_examples.html new file mode 100644 index 0000000000..1305f59d4a --- /dev/null +++ b/lib/xmerl/doc/src/xmerl_examples.html @@ -0,0 +1,408 @@ + + + +Customization functions + + + +

Customization functions

+

1 Description

+

The XML processor offers a number of hooks for + customization. These hooks are defined as function objects, and + can be provided by the caller.

+ +

The following customization functions are available. If + they also have access to their own state variable, the access + function for this state is identified within parentheses:

+ +
    + +
  • event function ( + xmerl_scan:event_state/[1,2] + )
  • + +
  • hook function ( + xmerl_scan:hook_state/[1,2] + )
  • + +
  • fetch function ( + xmerl_scan:fetch_state/[1,2] ) +
  • + +
  • continuation function ( + xmerl_scan:cont_state/[1,2] ) +
  • + +
  • rules function ( + xmerl_scan:rules_state/[1,2] ) +
  • + +
  • accumulator function
  • + +
  • close function
  • + +
+ +

For all of the above state access functions, the function + with one argument + (e.g. event_state(GlobalState)) + will read the state variable, while the function with two + arguments (e.g.: event_state(NewEventState, + GlobalState)) will modify it.

+ +

For each function, the description starts with the syntax + for specifying the function in the + Option_list. + The general forms are {Tag, Fun}, or + {Tag, Fun, LocalState}. The + second form can be used to initialize the state variable in + question.

+ + +

1.1 User State

+ +

All customization functions are free to access a + "User state" variable. Care must of course be taken + to coordinate the use of this state. It is recommended that + functions, which do not really have anything to contribute to + the "global" user state, use their own state + variable instead. Another option (used in + e.g. xmerl_eventp.erl) is for + customization functions to share one of the local states (in + xmerl_eventp.erl, the + continuation function and the fetch function both acces the + cont_state.)

+ +

Functions to access user state:

+ +
    + +
  • + xmerl_scan:user_state(GlobalState) +
  • + +
  • xmerl_scan:user_state(UserState, + GlobalState)
  • + +
+ + + +

1.2 Event Function

+ +

{event_fun, fun()} | {event_fun, fun(), + EventState}

+ +

The event function is called at the beginning and at the + end of a parsed entity. It has the following format and + semantics:

+ +

+
+ fun(Event, GlobalState) ->
+    EventState = xmerl_scan:event_state(GlobalState),
+    EventState2 = foo(Event, EventState),
+    GlobalState2 = xmerl_scan:event_state(EventState2, GlobalState)
+ end.
+ 
+ + + +

1.3 Hook Function

+

{hook_fun, fun()} | {hook_fun, fun(), + HookState}

+ + + +

The hook function is called when the processor has parsed a complete + entity. Format and semantics:

+ +

+
+ fun(Entity, GlobalState) ->
+    HookState = xmerl_scan:hook_state(GlobalState),
+    {TransformedEntity, HookState2} = foo(Entity, HookState),
+    GlobalState2 = xmerl_scan:hook_state(HookState2, GlobalState),
+    {TransformedEntity, GlobalState2}
+ end.
+ 
+ +

The relationship between the event function, the hook + function and the accumulator function is as follows:

+ +
    +
  1. The event function is first called with an + 'ended' event for the parsed entity.
  2. + +
  3. The hook function is called, possibly + re-formatting the entity.
  4. + +
  5. The acc function is called in order to + (optionally) add the re-formatted entity to the contents of + its parent element.
  6. + +
+ + + +

1.4 Fetch Function

+

+ {fetch_fun, fun()} | {fetch_fun, fun(), FetchState} +

+

The fetch function is called in order to fetch an external resource + (e.g. a DTD).

+ +

The fetch function can respond with three different return values:

+ +

+
+     Result ::=
+       {ok, {file, Filename}, NewGlobalState} |
+       {ok, {string, String}, NewGlobalState} |
+       {ok, not_fetched, NewGlobalState}
+ 
+ +

Format and semantics:

+ +

+
+ fun(URI, GlobalState) ->
+    FetchState = xmerl_scan:fetch_state(GlobalState),
+    Result = foo(URI, FetchState).  % Result being one of the above
+ end.
+ 
+ + + +

1.5 Continuation Function

+

+ {continuation_fun, fun()} | {continuation_fun, fun(), ContinuationState} +

+

The continuation function is called when the parser encounters the end + of the byte stream. Format and semantics:

+ +

+
+ fun(Continue, Exception, GlobalState) ->
+    ContState = xmerl_scan:cont_state(GlobalState),
+    {Result, ContState2} = get_more_bytes(ContState),
+    case Result of
+       [] ->
+          GlobalState2 = xmerl_scan:cont_state(ContState2, GlobalState),
+          Exception(GlobalState2);
+       MoreBytes ->
+          {MoreBytes2, Rest} = end_on_whitespace_char(MoreBytes),
+          ContState3 = update_cont_state(Rest, ContState2),
+          GlobalState3 = xmerl_scan:cont_state(ContState3, GlobalState),
+          Continue(MoreBytes2, GlobalState3)
+    end
+ end.
+ 
+ + +

1.6 Rules Functions

+

+ + {rules, ReadFun : fun(), WriteFun : fun(), RulesState} | + {rules, Table : ets()} +

+

The rules functions take care of storing scanner + information in a rules database. User-provided rules functions + may opt to store the information in mnesia, or perhaps in the + user_state(RulesState).

+ +

The following modes exist:

+ +
    + +
  • If the user doesn't specify an option, the + scanner creates an ets table, and uses built-in functions to + read and write data to it. When the scanner is done, the ets + table is deleted.
  • + +
  • If the user specifies an ets table via the + {rules, Table} option, the + scanner uses this table. When the scanner is done, it does + not delete the table.
  • + +
  • If the user specifies read and write + functions, the scanner will use them instead.
  • + +
+ +

The format for the read and write functions are as + follows:

+ + +

+
+ WriteFun(Context, Name, Definition, ScannerState) -> NewScannerState.
+ ReadFun(Context, Name, ScannerState) -> Definition | undefined.
+ 
+ +

Here is a summary of the data objects currently being + written by the scanner:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ContextKey ValueDefinition
notationNotationName{system, SL} | {public, PIDL, SL}
elem_defElementName#xmlElement{content = ContentSpec}
parameter_entityPENamePEDef
entityEntityNameEntityDef
Table 1 - 1 Scanner data objects
+ +

where

+

+
+ ContentSpec ::= empty | any | ElemContent
+ ElemContent ::= {Mode, Elems}
+ Mode        ::= seq | choice
+ Elems       ::= [Elem]
+ Elem        ::= '#PCDATA' | Name | ElemContent | {Occurrence, Elems}
+ Occurrence  ::= '*' | '?' | '+'
+ 
+ +
+

+ NOTE: When <Elem> is not wrapped with + <Occurrence>, (Occurrence = once) is implied.

+ + + +

1.7 Accumulator Function

+

{acc_fun, fun()}

+ +

The accumulator function is called to accumulate the + contents of an entity.When parsing very large files, it may + not be desireable to do so.In this case, an acc function can + be provided that simply doesn't accumulate.

+ +

Note that it is possible to even modify the parsed + entity before accumulating it, but this must be done with + care. xmerl_scan performs + post-processing of the element for namespace management. Thus, + the element must keep its original structure for this to + work.

+ +

The acc function has the following format and + semantics:

+ +

+
+ %% default accumulating acc fun
+ fun(ParsedEntity, Acc, GlobalState) ->
+    {[ParsedEntity|Acc], GlobalState}.
+
+ %% non-accumulating acc fun
+ fun(ParsedEntity, Acc, GlobalState) ->
+    {Acc, GlobalState}.
+ 
+ + +

1.8 Close Function

+ +

The close function is called when a document (either the + main document or an external DTD) has been completely + parsed. When xmerl_scan was started using + xmerl_scan:file/[1,2], the + file will be read in full, and closed immediately, before the + parsing starts, so when the close function is called, it will + not need to actually close the file. In this case, the close + function will be a good place to modify the state + variables.

+ +

Format and semantics:

+ +

+
+ fun(GlobalState) ->
+    GlobalState1 = ....  % state variables may be altered
+ 
+ + +

2 Examples

+

+See xmerl_test.erl for more examples. +

+ +

2.1 Handling spaces

+

+The following sample program illustrates three ways of +scanning a document: +

    +
  1. the default scan, which leaves whitespace untouched +
  2. normalizing spaces +
  3. normalizing spaces, then removing text elements that only + contain one space. +
+ +

+

+-module(tmp).
+
+-include("xmerl.hrl").
+
+-export([file1/1,
+	 file2/1,
+	 file3/1]).
+
+file1(F) ->
+    xmerl_scan:file(F).
+
+file2(F) ->
+    xmerl_scan:file(F, [{space,normalize}]).
+
+file3(F) ->
+    Acc = fun(#xmlText{value = " ", pos = P}, Acc, S) ->
+		  {Acc, P, S};  % new return format
+	     (X, Acc, S) ->
+		  {[X|Acc], S}
+	  end,
+    xmerl_scan:file(F, [{space,normalize}, {acc_fun, Acc}]).
+
+
+ + + + + + diff --git a/lib/xmerl/doc/src/xmerl_sax_parser.xml b/lib/xmerl/doc/src/xmerl_sax_parser.xml new file mode 100644 index 0000000000..ea63ba22a1 --- /dev/null +++ b/lib/xmerl/doc/src/xmerl_sax_parser.xml @@ -0,0 +1,426 @@ + + + + +
+ + 2008 + 2008 + Ericsson AB, All Rights Reserved + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + The Initial Developer of the Original Code is Ericsson AB. + + + xmerl_sax_parser + + + + +
+ + xmerl_sax_parser + XML SAX parser API + + +

+ A SAX parser for XML that sends the events through a callback interface. + SAX is the Simple API for XML, originally a Java-only API. SAX was the first widely adopted API for + XML in Java, and is a de facto standard where there are versions for several programming language + environments other than Java. +

+
+ +
+ DATA TYPES + + + option() + +

+ Options used to customize the behaviour of the parser. + Possible options are: +

+ + {continuation_fun, ContinuationFun} + + ContinuationFun is a call back function to decide what to do if + the parser runs into EOF before the document is complete. + + {continuation_state, term()} + + State that is accessible in the continuation call back function. + + {event_fun, EventFun} + + EventFun is the call back function for parser events. + + {event_state, term()} + + State that is accessible in the event call back function. + + {file_type, FileType} + + Flag that tells the parser if it's parsing a DTD or a normal XML file (default normal). + + FileType = normal | dtd + + + {encoding, Encoding} + + Set default character set used (default UTF-8). This character set is used only if not explicitly + given by the XML document. + + Encoding = utf8 | {utf16,big} | {utf16,little} | latin1 | list + + + skip_external_dtd + + Skips the external DTD during parsing. + + +
+ + +

+
+ event() + +

+ The SAX events that are sent to the user via the callback. +

+ + + startDocument + + Receive notification of the beginning of a document. The SAX parser will send this event only once + before any other event callbacks. + + + endDocument + + Receive notification of the end of a document. The SAX parser will send this event only once, and it will + be the last event during the parse. + + + {startPrefixMapping, Prefix, Uri} + + Begin the scope of a prefix-URI Namespace mapping. + Note that start/endPrefixMapping events are not guaranteed to be properly nested relative to each other: + all startPrefixMapping events will occur immediately before the corresponding startElement event, and all + endPrefixMapping events will occur immediately after the corresponding endElement event, but their + order is not otherwise guaranteed. + There will not be start/endPrefixMapping events for the "xml" prefix, since it is predeclared and immutable. + + Prefix = string() + Uri = string() + + + + {endPrefixMapping, Prefix} + + End the scope of a prefix-URI mapping. + + Prefix = string() + + + + {startElement, Uri, LocalName, QualifiedName, Attributes} + + Receive notification of the beginning of an element. + + The Parser will send this event at the beginning of every element in the XML document; + there will be a corresponding endElement event for every startElement event (even when the element is empty). + All of the element's content will be reported, in order, before the corresponding endElement event. + + Uri = string() + LocalName = string() + QualifiedName = {Prefix, LocalName} + Prefix = string() + Attributes = [{Uri, Prefix, AttributeName, Value}] + AttributeName = string() + Value = string() + + + + {endElement, Uri, LocalName, QualifiedName} + + Receive notification of the end of an element. + + The SAX parser will send this event at the end of every element in the XML document; + there will be a corresponding startElement event for every endElement event (even when the element is empty). + + Uri = string() + LocalName = string() + QualifiedName = {Prefix, LocalName} + Prefix = string() + + + + {characters, string()} + + Receive notification of character data. + + + {ignorableWhitespace, string()} + + Receive notification of ignorable whitespace in element content. + + + {processingInstruction, Target, Data} + + Receive notification of a processing instruction. + + The Parser will send this event once for each processing instruction found: + note that processing instructions may occur before or after the main document element. + + Target = string() + Data = string() + + + + {comment, string()} + + Report an XML comment anywhere in the document (both inside and outside of the document element). + + + startCDATA + + Report the start of a CDATA section. The contents of the CDATA section will be reported + through the regular characters event. + + + endCDATA + + Report the end of a CDATA section. + + + startDTD + + Report the start of DTD declarations, it's reporting the start of the DOCTYPE declaration. + If the document has no DOCTYPE declaration, this event will not be sent. + + + endDTD + + Report the end of DTD declarations, it's reporting the end of the DOCTYPE declaration. + + + {startEntity, SysId} + + Report the beginning of some internal and external XML entities. ??? + + + {endEntity, SysId} + + Report the end of an entity. ??? + + + {elementDecl, Name, Model} + + Report an element type declaration. + The content model will consist of the string "EMPTY", the string "ANY", or a parenthesised group, + optionally followed by an occurrence indicator. The model will be normalized so that all parameter + entities are fully resolved and all whitespace is removed,and will include the enclosing parentheses. + Other normalization (such as removing redundant parentheses or simplifying occurrence indicators) + is at the discretion of the parser. + + Name = string() + Model = string() + + + + {attributeDecl, ElementName, AttributeName, Type, Mode, Value} + + Report an attribute type declaration. + + ElementName = string() + AttributeName = string() + Type = string() + Mode = string() + Value = string() + + + + {internalEntityDecl, Name, Value} + + Report an internal entity declaration. + + Name = string() + Value = string() + + + + {externalEntityDecl, Name, PublicId, SystemId} + + Report a parsed external entity declaration. + + Name = string() + PublicId = string() + SystemId = string() + + + + {unparsedEntityDecl, Name, PublicId, SystemId, Ndata} + + Receive notification of an unparsed entity declaration event. + + Name = string() + PublicId = string() + SystemId = string() + Ndata = string() + + + + {notationDecl, Name, PublicId, SystemId} + + Receive notification of a notation declaration event. + + Name = string() + PublicId = string() + SystemId = string() + + + + +
+ + unicode_char() + + Integer representing valid unicode codepoint. + + + unicode_binary() + + Binary with characters encoded in UTF-8 or UTF-16. + + + latin1_binary() + + Binary with characters encoded in iso-latin-1. + + +
+ +
+ + + + + + file(Filename, Options) -> Result + Parse file containing an XML document. + + Filename = string() + Options = [option()] + Result = {ok, EventState, Rest} | +    {Tag, Location, Reason, EndTags, EventState} + Rest = unicode_binary() | latin1_binary() + Tag = atom() (fatal_error, or user defined tag) + Location = {CurrentLocation, EntityName, LineNo} + CurrentLocation = string() + EntityName = string() + LineNo = integer() + EventState = term() + Reason = term() + + +

Parse file containing an XML document. This functions uses a default continuation function to read the file in blocks.

+
+
+ + + stream(Xml, Options) -> Result + Parse a stream containing an XML document. + + Xml = unicode_binary() | latin1_binary() | [unicode_char()] + Options = [option()] + Result = {ok, EventState, Rest} | +    {Tag, Location, Reason, EndTags, EventState} + Rest = unicode_binary() | latin1_binary() | [unicode_char()] + Tag = atom() (fatal_error or user defined tag) + Location = {CurrentLocation, EntityName, LineNo} + CurrentLocation = string() + EntityName = string() + LineNo = integer() + EventState = term() + Reason = term() + + +

Parse a stream containing an XML document.

+
+
+ +
+ +
+ CALLBACK FUNCTIONS +

+ The callback interface is based on that the user sends a fun with the + correct signature to the parser. +

+
+ + + + + ContinuationFun(State) -> {NewBytes, NewState} + Continuation call back function. + + State = NewState = term() + NewBytes = binary() | list() (should be same as start input in stream/2) + + +

+ This function is called whenever the parser runs out of input data. + If the function can't get hold of more input an empty list or binary + (depends on start input in stream/2) is returned. + + Other types of errors is handled through exceptions. Use throw/1 to send the + following tuple {Tag = atom(), Reason = string()} if the continuation function encounters a fatal error. + Tag is an atom that identifies the functional entity that sends the exception + and Reason is a string that describes the problem. +

+
+
+ + + EventFun(Event, Location, State) -> NewState + Event call back function. + + Event = event() + Location = {CurrentLocation, Entityname, LineNo} + CurrentLocation = string() + Entityname = string() + LineNo = integer() + State = NewState = term() + + +

+ This function is called for every event sent by the parser. + + The error handling is done through exceptions. Use throw/1 to send the + following tuple {Tag = atom(), Reason = string()} if the application encounters a fatal error. + Tag is an atom that identifies the functional entity that sends the exception + and Reason is a string that describes the problem. +

+
+
+ +
+ + + +
+ diff --git a/lib/xmerl/doc/src/xmerl_ug.xmlsrc b/lib/xmerl/doc/src/xmerl_ug.xmlsrc new file mode 100644 index 0000000000..6ee6707e53 --- /dev/null +++ b/lib/xmerl/doc/src/xmerl_ug.xmlsrc @@ -0,0 +1,490 @@ + + + + +
+ + 20042009 + Ericsson AB. All Rights Reserved. + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + + + xmerl + UKH/L Bertil Karlsson + + 2004-06-16 + D + xmerl_ug.xml +
+ +
+ Introduction + +
+ Features +

The xmerl XML parser is able to parse XML documents + according to the XML 1.0 standard. As default it performs + well-formed parsing,(syntax checks and checks of well-formed + constraints). Optionally one can also use xmerl as a validating + parser,(validate according to referenced DTD and validating + constraints). By means of for example the xmerl_xs module it is + possible to transform the parsed result to other formats, + e.g. text, HTML, XML etc.

+
+ +
+ Overview +

This document does not give an introduction to XML. There + are a lot of books available that describe XML from + different views. At the www.W3.org site you will find + the XML 1.0 specification and other related specs. One site were + you can find tutorials on XML and related specs is ZVON.org.

+

However, here you will find some examples of how to use + and to what you can use xmerl. A detailed description of the + user interface can be found in the reference manual.

+

There are two known shortcomings in xmerl:

+ + It cannot retrieve external entities on the Internet + by a URL reference, only resources in the local file + system. + xmerl can parse Unicode encoded data. But, it fails + on tag names, attribute names and other mark-up names that + are encoded Unicode characters not mapping on ASCII. + +

By parsing an XML document you will get a record, + displaying the structure of the document, as return + value. The record also holds the data of the document. xmerl + is convenient to use in for instance the following scenarios:

+

You need to retrieve data from XML documents. Your + Erlang software can handle information from the XML document + by extracting data from the data structure received by + parsing.

+

It is also possible to do further processing of parsed + XML with xmerl. If you want to change format of the XML + document to for instance HTML, text or other XML format you + can transform it. There is support for such transformations + in xmerl.

+

One may also convert arbitrary data to XML. So it for + instance is easy to make it readable by humans. In this case + you first create xmerl data structures out of your data, then + transform it to XML.

+

You can find examples of these three examples of usage + below.

+
+
+ +
+ xmerl User Interface Data Structure +

The following records used by xmerl to save the parsed + data are defined in xmerl.hrl

+

The result of a successful parsing is a tuple + {DataStructure,M}. M is the XML production Misc, + which is the mark-up that comes after the element of the + document. It is returned "as is". DataStructure is an + xmlElement record, that among others have the fields + name, parents, attributes and + content like:

+
+#xmlElement{name=Name,
+            ...
+            parents=Parents,
+            ...
+            attributes=Attrs,
+            content=Content,
+            ...}    
+

The name of the element is found in the name + field. In the parents field is the names of the parent + elements saved. Parents is a list of tuples where the first + element in each tuple is the name of the parent element. The + list is in reverse order.

+

The record xmlAttribute holds the name and value of + an attribute in the fields name and value. All + attributes of an element is a list of xmlAttribute in the + field attributes of the xmlElement record. +

+

The content field of the top element is a list of + records that shows the structure and data of the document. If + it is a simple document like:

+
+<?xml version="1.0"?>
+<dog>
+Grand Danois
+</dog>    
+

The parse result will be:

+
+#xmlElement{name = dog,
+            ...
+            parents = [],
+            ...
+            attributes = [],
+            content = [{xmlText,[{dog,1}],1,[],"\
+Grand Danois\
+",text}],
+            ...
+            }    
+

Where the content of the top element is: + [{xmlText,[{dog,1}],1,[],"\ Grand Danois\ ",text}]. Text will be returned in xmlText records. Though, + usually documents are more complex, and the content of the top + element will in that case be a nested structure with + xmlElement records that in turn may have complex content. All of + this reflects the structure of the XML document.

+

Space characters between mark-up as space, + tab and line feed are normalized and returned as + xmlText records.

+ +
+ Errors +

An unsuccessful parse results in an error, which may be a + tuple {error,Reason} or an exit: + {'EXIT',Reason}. According to the XML 1.0 standard + there are fatal error and error situations. The + fatal errors must be detected by a conforming parser + while an error may be detected. Both categories of + errors are reported as fatal errors by this version of xmerl, + most often as an exit.

+
+
+ +
+ Getting Started +

In the following examples we use the XML file + "motorcycles.xml" and the corresponding DTD + "motorcycles.dtd". motorcycles.xml looks like: + +

+ +

and motorcycles.dtd looks like:

+ +

If you want to parse the XML file motorcycles.xml you run + it in the Erlang shell like:

+
+3> {ParsResult,Misc}=xmerl_scan:file("motorcycles.xml"). 
+{{xmlElement,motorcycles,
+             motorcycles,
+             [],
+             {xmlNamespace,[],[]},
+             [],
+             1,
+             [],
+             [{xmlText,[{motorcycles,1}],1,[],"\
+  ",text},
+              {xmlElement,bike,
+                          bike,
+                          [],
+                          {xmlNamespace,[],[]},
+                          [{motorcycles,1}],
+                          2,
+                          [{xmlAttribute,year,[],[],[],[]|...},
+                           {xmlAttribute,color,[],[],[]|...}],
+                          [{xmlText,[{bike,2},{motorcycles|...}],
+                                    1,
+                                    []|...},
+                           {xmlElement,name,name,[]|...},
+                           {xmlText,[{...}|...],3|...},
+                           {xmlElement,engine|...},
+                           {xmlText|...},
+                           {...}|...],
+                          [],
+                          ".",
+                          undeclared},
+              ...
+              ],
+             [],
+             ".",
+             undeclared},
+ []}
+4>     
+

If you instead receives the XML doc as a string you can + parse it by xmerl_scan:string/1. Both file/2 and string/2 + exists where the second argument is a list of options to the + parser, see the reference manual.

+
+ +
+ Example: Extracting Data From XML Content +

In this example consider the situation where you want to + examine a particular data in the XML file. For instance, you + want to check for how long each motorcycle have been recorded.

+

Take a look at the DTD and observe that the structure of an + XML document that is conformant to this DTD must have one + motorcycles element (the root element). The motorcycles element + must have at least one bike element. After each bike element it + may be a date element. The content of the date element is + #PCDATA (Parsed Character DATA), i.e. raw text. Observe that if + #PCDATA must have a or a character it must + be written as and + respectively. Also other character entities exists similar to + the ones in HTML and SGML.

+

If you successfully parse the XML file with the validation + on as in: + xmerl_scan:file('motorcycles.xml',[{validation,true}]) + you know that the XML document is valid and has the structure + according to the DTD.

+

Thus, knowing the allowed structure it is easy to write a + program that traverses the data structure and picks the + information in the xmlElements records with name date.

+

Observe that white space: each space, tab or line feed, + between mark-up results in an xmlText record.

+

+
+ +
+ Example: Create XML Out Of Arbitrary Data +

For this task there are more than one way to go. The "brute + force" method is to create the records you need and feed your + data in the content and attribute fields of the appropriate + element.

+

There is support for this in xmerl by the "simple-form" + format. You can put your data in a simple-form data structure + and feed it into + xmerl:export_simple(Content,Callback,RootAttributes). Content + may be a mixture of simple-form and xmerl records as xmlElement + and xmlText.

+

The Types are:

+ + Content = [Element] + Callback = atom() + RootAttributes = [Attributes] + +

Element is any of:

+ + {Tag, Attributes, Content} + {Tag, Content} + Tag + IOString + #xmlText{} + #xmlElement{} + #xmlPI{} + #xmlComment{} + #xmlDecl{} + +

The simple-form structure is any of {Tag, Attributes, Content}, {Tag, Content} or Tag where:

+

+ + Tag = atom() + Attributes = [{Name, Value}| #xmlAttribute{}] + Name = atom() + Value = IOString | atom() | integer() + +

See also reference manual for + xmerl

+

If you want to add the information about a black Harley + Davidsson 1200 cc Sportster motorcycle from 2003 that is in + shape as new in the motorcycles.xml document you can put the + data in a simple-form data structure like:

+
+Data =
+  {bike,
+     [{year,"2003"},{color,"black"},{condition,"new"}],
+     [{name,
+         [{manufacturer,["Harley Davidsson"]},
+          {brandName,["XL1200C"]},
+          {additionalName,["Sportster"]}]},
+      {engine,
+         ["V-engine, 2-cylinders, 1200 cc"]},
+      {kind,["custom"]},
+      {drive,["belt"]}]}    
+

In order to append this data to the end of the + motorcycles.xml document you have to parse the file and add Data + to the end of the root element content.

+
+    {RootEl,Misc}=xmerl_scan:file('motorcycles.xml'),
+    #xmlElement{content=Content} = RootEl,
+    NewContent=Content++lists:flatten([Data]),
+    NewRootEl=RootEl#xmlElement{content=NewContent},    
+

Then you can run it through the export_simple/2 function:

+
+    {ok,IOF}=file:open('new_motorcycles.xml',[write]),
+    Export=xmerl:export_simple([NewRootEl],xmerl_xml),
+    io:format(IOF,"~s~n",[lists:flatten(Export)]),    
+ +

The result would be:

+ +

If it is important to get similar indentation and newlines + as in the original document you have to add #xmlText{} records + with space and newline values in appropriate places. It may also + be necessary to keep the original prolog where the DTD is + referenced. If so, it is possible to pass a RootAttribute + {prolog,Value} to export_simple/3. The following + example code fixes those changes in the previous example:

+
+    Data =
+      [#xmlText{value="  "},
+       {bike,[{year,"2003"},{color,"black"},{condition,"new"}],
+             [#xmlText{value="\
+    "},
+              {name,[#xmlText{value="\
+      "},
+                     {manufacturer,["Harley Davidsson"]},
+                     #xmlText{value="\
+      "},
+                     {brandName,["XL1200C"]},
+                     #xmlText{value="\
+      "},
+                     {additionalName,["Sportster"]},
+                     #xmlText{value="\
+    "}]},
+              {engine,["V-engine, 2-cylinders, 1200 cc"]},
+              #xmlText{value="\
+    "},
+              {kind,["custom"]},
+              #xmlText{value="\
+    "},
+              {drive,["belt"]},
+              #xmlText{value="\
+  "}]},
+       #xmlText{value="\
+"}],
+    ...
+    NewContent=Content++lists:flatten([Data]),
+    NewRootEl=RootEl#xmlElement{content=NewContent},
+    ...
+    Prolog = ["<?xml version=\\"1.0\\" encoding=\\"utf-8\\" ?>
+<!DOCTYPE motorcycles SYSTEM \\"motorcycles.dtd\\">\
+"],
+    Export=xmerl:export_simple([NewRootEl],xmerl_xml,[{prolog,Prolog}]),
+    ...    
+

The result will be:

+ +
+ +
+ Example: Transforming XML To HTML +

Assume that you want to transform the motorcycles.xml document to + HTML. If you want the same structure and tags of the resulting + HTML document as of the XML document then you can use the + xmerl:export/2 function. The following:

+
+2> {Doc,Misc}=xmerl_scan:file('motorcycles.xml').
+{{xmlElement,motorcycles,
+             motorcycles,
+             [],
+             {xmlNamespace,[],[]},
+             [],
+             1,
+             [],
+             [{xmlText,[{motorcycles,1}],1,[],"\
+  ",text},
+              {xmlElement,bike,
+...
+3> DocHtml=xmerl:export([Doc],xmerl_html).
+["<!DOCTYPE HTML PUBLIC \\"",
+ "-//W3C//DTD HTML 4.01 Transitional//EN",
+ "\\"",
+ [],
+ ">\
+",
+ [[["<","motorcycles",">"],
+   ["\
+  ",
+    [["<",
+      "bike",
+      [[" ","year","=\\"","2000","\\""],[" ","color","=\\"","black","\\""]],
+      ">"],
+...    
+

Will give the result result_export.html

+

Perhaps you want to do something more arranged for human + reading. Suppose that you want to list all different brands in + the beginning with links to each group of motorcycles. You also + want all motorcycles sorted by brand, then some flashy colors + on top of it. Thus you rearrange the order of the elements and + put in arbitrary HTML tags. This is possible to do by means of + the XSL Transformation (XSLT) like functionality in xmerl.

+

Even though the following example shows one way to transform data + from XML to HTML it also applies to transformations to other + formats.

+

xmerl_xs does not implement the entire XSLT + specification but the basic functionality. For all details see + the reference manual

+

First, some words about the xmerl_xs functionality:

+

You need to wright template functions to be able to control + what kind of output you want. Thus if you want to encapsulate a + bike element in <p> tags you simply wright a + function:

+
+template(E = #xmlElement{name='bike'}) ->
+    ["<p>",xslapply(fun template/1,E),"</p>"];    
+

With xslapply you tell the XSLT processor in which + order it should traverse the XML structure. By default it goes + in preorder traversal, but with the following we make a + deliberate choice to break that order:

+
+template(E = #xmlElement{name='bike'}) ->
+    ["<p>",xslapply(fun template/1,select("bike/name/manufacturer")),"</p>"];    
+

If you want to output the content of an XML element or an attribute you will get the value as a string by the value_of function:

+
+template(E = #xmlElement{name='motorcycles'}) ->
+    ["<p>",value_of(select("bike/name/manufacturer",E),"</p>"];    
+

In the xmerl_xs functions you can provide a select(String) + call, which is an XPath + functionality. For more details see the xmerl_xs tutorial.

+

Now, back to the example where we wanted to make the output + more arranged. With the template:

+
+template(E = #xmlElement{name='motorcycles'}) ->
+    [    "<head>\
+<title>motorcycles</title>\
+</head>\
+",
+         "<body>\
+",
+\011 "<h1>Used Motorcycles</h1>\
+",
+\011 "<ul>\
+",
+\011 remove_duplicates(value_of(select("bike/name/manufacturer",E))),
+\011 "\
+</ul>\
+",
+\011 sort_by_manufacturer(xslapply(fun template/1, E)),
+         "</body>\
+",
+\011 "</html>\
+"];    
+

We match on the top element and embed the inner parts in an + HTML body. Then we extract the string values of all motorcycle + brands, sort them and removes duplicates by + remove_duplicates(value_of(select("bike/name/manufacturer", E))). We also process the substructure of the top element + and pass it to a function that sorts all motorcycle information + by brand according to the task formulation in the beginning of + this example.

+

The next template matches on the bike element:

+
+template(E = #xmlElement{name='bike'}) ->
+    {value_of(select("name/manufacturer",E)),["<dt>",xslapply(fun template/1,select("name",E)),"</dt>",
+    "<dd><ul>\
+",
+    "<li style="color:green">Manufacturing year: ",xslapply(fun template/1,select("@year",E)),"</li>\
+",
+    "<li style="color:red">Color: ",xslapply(fun template/1,select("@color",E)),"</li>\
+",
+    "<li style="color:blue">Shape : ",xslapply(fun template/1,select("@condition",E)),"</li>\
+",
+    "</ul></dd>\
+"]};    
+

This creates a tuple with the brand of the motorcycle and + the output format. We use the brand name only for sorting + purpose. We have to end the template function with the "built + in clause" template(E) -> built_in_rules(fun template/1, E).

+

The entire program is motorcycles2html.erl:

+ +

If we run it like this: + motorcycles2html:process_to_file('result_xs.html', 'motorcycles2.xml'). The result will be result_xs.html. When the + input file is of the same structure as the previous + "motorcycles" XML files but it has a little more 'bike' + elements and the 'manufacturer' elements are not in order.

+
+
+ diff --git a/lib/xmerl/doc/src/xmerl_xs_examples.html b/lib/xmerl/doc/src/xmerl_xs_examples.html new file mode 100644 index 0000000000..aaa3bc5033 --- /dev/null +++ b/lib/xmerl/doc/src/xmerl_xs_examples.html @@ -0,0 +1,291 @@ + + + +XSLT like transformations in Erlang +

Examples

+
+

Example 1 Using xslapply

+

original XSLT:

+

+
+  <xsl:template match="doc/title">
+      <h1>
+        <xsl:apply-templates/>
+      </h1>
+  </xsl:template>
+  
+	    
+

+ becomes in Erlang:

+

+
+  template(E = #xmlElement{ parents=[{'doc',_}|_], name='title'}) ->
+      ["<h1>",
+           xslapply(fun template/1, E),
+       "</h1>"];
+  
+	    
+ +
+
+

Example 2 Using value_of and select

+

+
+  <xsl:template match="title">
+    <div align="center"><h1><xsl:value-of select="." /></h1></div>
+  </xsl:template>
+  
+	
+

+ becomes: +

+

+
+template(E = #xmlElement{name='title'}) ->
+    ["<div align=\"center\"><h1>", value_of(select(".", E)), "</h1></div>"];
+  
+	    
+
+
+

Example 3 Simple xsl stylesheet

+

+ A complete example with the XSLT sheet in the xmerl distribution. +

+

+
+
+<xsl:stylesheet version="1.0"
+		xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+		xmlns="http://www.w3.org/TR/xhtml1/strict">
+
+  <xsl:strip-space elements="doc chapter section"/>
+  <xsl:output
+	method="xml"
+	indent="yes"
+	encoding="iso-8859-1"
+  />
+
+  <xsl:template match="doc">
+    <html>
+      <head>
+        <title>
+          <xsl:value-of select="title"/>
+        </title>
+      </head>
+      <body>
+        <xsl:apply-templates/>
+      </body>
+    </html>
+  </xsl:template>
+
+  <xsl:template match="doc/title">
+    <h1>
+      <xsl:apply-templates/>
+    </h1>
+  </xsl:template>
+
+  <xsl:template match="chapter/title">
+    <h2>
+      <xsl:apply-templates/>
+    </h2>
+  </xsl:template>
+
+  <xsl:template match="section/title">
+    <h3>
+      <xsl:apply-templates/>
+    </h3>
+  </xsl:template>
+
+  <xsl:template match="para">
+    <p>
+      <xsl:apply-templates/>
+    </p>
+  </xsl:template>
+
+  <xsl:template match="note">
+    <p class="note">
+      <b>NOTE: </b>
+      <xsl:apply-templates/>
+    </p>
+  </xsl:template>
+
+  <xsl:template match="emph">
+    <em>
+      <xsl:apply-templates/>
+    </em>
+  </xsl:template>
+
+</xsl:stylesheet>
+ 
+      
+
+
+

Example 4 Erlang version

+

+ Erlang transformation of previous example: +

+

+
+
+-include("xmerl.hrl").
+
+-import(xmerl_xs, 
+	[ xslapply/2, value_of/1, select/2, built_in_rules/2 ]).
+
+doctype()->
+    "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\
+ \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd \">".
+
+process_xml(Doc)->
+	template(Doc).
+
+template(E = #xmlElement{name='doc'})->
+    [ "<\?xml version=\"1.0\" encoding=\"iso-8859-1\"\?>",
+      doctype(),
+      "<html xmlns=\"http://www.w3.org/1999/xhtml\" >"
+      "<head>"
+      "<title>", value_of(select("title",E)), "</title>"
+      "</head>"
+      "<body>",
+      xslapply( fun template/1, E),
+      "</body>"
+      "</html>" ];
+
+
+template(E = #xmlElement{ parents=[{'doc',_}|_], name='title'}) ->
+    ["<h1>", 
+     xslapply( fun template/1, E), 
+     "</h1>"];
+
+template(E = #xmlElement{ parents=[{'chapter',_}|_], name='title'}) ->
+    ["<h2>", 
+     xslapply( fun template/1, E),
+     "</h2>"];
+
+template(E = #xmlElement{ parents=[{'section',_}|_], name='title'}) ->
+    ["<h3>", 
+     xslapply( fun template/1, E),
+     "</h3>"];
+
+template(E = #xmlElement{ name='para'}) ->
+    ["<p>", xslapply( fun template/1, E), "</p>"];
+
+template(E = #xmlElement{ name='note'}) ->
+    ["<p class=\"note\">"
+     "<b>NOTE: </b>",
+     xslapply( fun template/1, E),
+     "</p>"];
+
+template(E = #xmlElement{ name='emph'}) ->
+    ["<em>", xslapply( fun template/1, E), "</em>"];
+
+template(E)->
+    built_in_rules( fun template/1, E).
+ 
+      
+

+ It is important to end with a call to + xmerl_xs:built_in_rules/2 + if you want any text to be written in "push" transforms. + That are the ones using a lot xslapply( fun + template/1, E ) instead of + value_of(select("xpath",E)), + which is pull... +

+
+

The largest example is the stylesheet to transform this document + from the Simplified Docbook XML format to xhtml. The source + file is sdocbook2xhtml.erl. +

+ + +

Tips and tricks

+ +

for-each

+

The function for-each is quite common in XSLT stylesheets. + It can often be rewritten and replaced by select/1. Since + select/1 returns a list of #xmlElements and xslapply/2 + traverses them it is more or less the same as to loop over all + the elements. +

+ + +

position()

+

The XSLT position() and #xmlElement.pos are not the + same. One has to make an own position in Erlang.

+
+

Example 5 Counting positions

+

+
+<xsl:template match="stanza">
+  <p><xsl:apply-templates select="line" /></p>
+</xsl:template>
+
+<xsl:template match="line">
+  <xsl:if test="position() mod 2 = 0">&#160;&#160;</xsl:if>
+  <xsl:value-of select="." /><br />
+</xsl:template>
+ 
+	  
+

Can be written as

+

+
+template(E = #xmlElement{name='stanza'}) ->
+    {Lines,LineNo} = lists:mapfoldl(fun template_pos/2, 1, select("line", E)),
+    ["<p>", Lines, "</p>"].
+
+template_pos(E = #xmlElement{name='line'}, P) ->
+    {[indent_line(P rem 2), value_of(E#xmlElement.content), "<br />"], P + 1 }.
+
+indent_line(0)->"&#160;&#160;";
+indent_line(_)->"".
+ 
+	  
+
+ + +

Global tree awareness

+

In XSLT you have "root" access to the top of the tree + with XPath, even though you are somewhere deep in your + tree.

+

The xslapply/2 function only carries back the child part + of the tree to the template fun. But it is quite easy to write + template funs that handles both the child and top tree.

+
+

Example 6 Passing the root tree

+

The following example piece will prepend the article + title to any section title

+

+
+template(E = #xmlElement{name='title'}, ETop ) ->
+    ["<h3>", value_of(select("title", ETop))," - ",
+     xslapply( fun(A) -> template(A, ETop) end, E),
+     "</h3>"];
+ 
+	  
+
+ \ No newline at end of file -- cgit v1.2.3