diff options
Diffstat (limited to 'lib/xmerl/src/xmerl_xs.erl')
-rw-r--r-- | lib/xmerl/src/xmerl_xs.erl | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/lib/xmerl/src/xmerl_xs.erl b/lib/xmerl/src/xmerl_xs.erl new file mode 100644 index 0000000000..f42a470a43 --- /dev/null +++ b/lib/xmerl/src/xmerl_xs.erl @@ -0,0 +1,123 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2003-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% +%% + +%% Description : Implements XSLT like transformations in Erlang + +%% @doc +% Erlang has similarities to XSLT since both languages +% have a functional programming approach. Using <code>xmerl_xpath</code> +% it is possible to write XSLT like transforms in Erlang. +% +% <p>XSLT stylesheets are often used when transforming XML +% documents, to other XML documents or (X)HTML for presentation. +% XSLT contains quite many +% functions and learning them all may take some effort. +% This document assumes a basic level of +% understanding of XSLT. +% </p> +% <p>Since XSLT is based on a functional programming approach +% with pattern matching and recursion it is possible to write +% similar style sheets in Erlang. At least for basic +% transforms. This +% document describes how to use the XPath implementation together +% with Erlangs pattern matching and a couple of functions to write +% XSLT like transforms.</p> +% <p>This approach is probably easier for an Erlanger but +% if you need to use real XSLT stylesheets in order to "comply to +% the standard" there is an adapter available to the Sablotron +% XSLT package which is written i C++. +% See also the <a href="xmerl_xs_examples.html">Tutorial</a>. +% </p> + +-module(xmerl_xs). + +-export([xslapply/2, value_of/1, select/2, built_in_rules/2 ]). +-include("xmerl.hrl"). + + +%% @spec xslapply(Function, EList::list()) -> List +%% Function = () -> list() +%% @doc xslapply is a wrapper to make things look similar to +%% xsl:apply-templates. +%% +%% <p>Example, original XSLT:</p><br/><pre> +%% <xsl:template match="doc/title"> +%% <h1> +%% <xsl:apply-templates/> +%% </h1> +%% </xsl:template> +%% </pre> +%% +%% <p>becomes in Erlang:</p><br/><pre> +%% template(E = #xmlElement{ parents=[{'doc',_}|_], name='title'}) -> +%% ["<h1>", +%% xslapply(fun template/1, E), +%% "</h1>"]; +%% </pre> + +xslapply(Fun, EList) when is_list(EList) -> + lists:map( Fun, EList); +xslapply(Fun, E = #xmlElement{})-> + lists:map( Fun, E#xmlElement.content). + + +%% @spec value_of(E) -> List +%% E = unknown() +%% +%% @doc Concatenates all text nodes within the tree. +%% +%% <p>Example:</p><br/><pre> +%% <xsl:template match="title"> +%% <div align="center"> +%% <h1><xsl:value-of select="." /></h1> +%% </div> +%% </xsl:template> +%% </pre> +%% +%% <p>becomes:</p><br/> <pre> +%% template(E = #xmlElement{name='title'}) -> +%% ["<div align="center"><h1>", +%% value_of(select(".", E)), "</h1></div>"] +%% </pre> +value_of(E)-> + lists:reverse(xmerl_lib:foldxml(fun value_of1/2, [], E)). + +value_of1(#xmlText{}=T1, Accu)-> + [xmerl_lib:export_text(T1#xmlText.value)|Accu]; +value_of1(_, Accu) -> + Accu. + +%% @spec select(String::string(),E)-> E +%% +%% @doc Extracts the nodes from the xml tree according to XPath. +%% @see value_of/1 +select(Str,E)-> + xmerl_xpath:string(Str,E). + +%% @spec built_in_rules(Fun, E) -> List +%% +%% @doc The default fallback behaviour. Template funs should end with: +%% <br/><code>template(E) -> built_in_rules(fun template/1, E)</code>. +built_in_rules(Fun, E = #xmlElement{})-> + lists:map(Fun, E#xmlElement.content); +built_in_rules(_Fun, E = #xmlText{}) -> + xmerl_lib:export_text(E#xmlText.value); +built_in_rules(_Fun, E = #xmlAttribute{}) -> + E#xmlAttribute.value; +built_in_rules(_Fun, _E) ->[]. |