aboutsummaryrefslogtreecommitdiffstats
path: root/lib/xmerl/src/xmerl_xs.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/xmerl/src/xmerl_xs.erl')
-rw-r--r--lib/xmerl/src/xmerl_xs.erl123
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>
+%% &lt;xsl:template match="doc/title">
+%% &lt;h1>
+%% &lt;xsl:apply-templates/>
+%% &lt;/h1>
+%% &lt;/xsl:template>
+%% </pre>
+%%
+%% <p>becomes in Erlang:</p><br/><pre>
+%% template(E = #xmlElement{ parents=[{'doc',_}|_], name='title'}) ->
+%% ["&lt;h1>",
+%% xslapply(fun template/1, E),
+%% "&lt;/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>
+%% &lt;xsl:template match="title">
+%% &lt;div align="center">
+%% &lt;h1>&lt;xsl:value-of select="." />&lt;/h1>
+%% &lt;/div>
+%% &lt;/xsl:template>
+%% </pre>
+%%
+%% <p>becomes:</p><br/> <pre>
+%% template(E = #xmlElement{name='title'}) ->
+%% ["&lt;div align="center">&lt;h1>",
+%% value_of(select(".", E)), "&lt;/h1>&lt;/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) ->[].