<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>XML, XSLT &#38; Java</title>
	<atom:link href="http://blog.expedimentum.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.expedimentum.com</link>
	<description>Texte und Metadaten verarbeiten. Fundstücke und Beispiele</description>
	<lastBuildDate>Thu, 17 May 2012 10:13:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Benutzerdefinierte Funktionen und externe Funktionsbibliotheken in Schematron</title>
		<link>http://blog.expedimentum.com/2012/benutzerdefinierte-funktionen-funktionsbibliotheken-schematron/</link>
		<comments>http://blog.expedimentum.com/2012/benutzerdefinierte-funktionen-funktionsbibliotheken-schematron/#comments</comments>
		<pubDate>Tue, 01 May 2012 20:14:53 +0000</pubDate>
		<dc:creator>Stf</dc:creator>
				<category><![CDATA[Beispiele]]></category>
		<category><![CDATA[Schematron]]></category>
		<category><![CDATA[XML-Validierung]]></category>
		<category><![CDATA[XSLT und XPath]]></category>

		<guid isPermaLink="false">http://blog.expedimentum.com/?p=578</guid>
		<description><![CDATA[In manchen Situationen reicht der Umfang von XPath oder auch von XPath&#160;2.0 nicht aus, um die gewünschten Tests zu formulieren, etwa wenn rekursive Funktionsaufrufe nötig sind. In anderen Situationen möchte man Algorithmen in verschiedenen Tests wiederverwenden. In solchen Situationen helfen benutzerdefinierte Funktionen weiter. Mit XSLT&#160;2.0 geht das recht einfach: &#60;schema xmlns=&#34;http://purl.oclc.org/dsdl/schematron&#34; xmlns:xsl=&#34;http://www.w3.org/1999/XSL/Transform&#34; queryBinding=&#34;xslt2&#34; &#62; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>In manchen Situationen reicht der Umfang von <a href="http://blog.expedimentum.com/glossar/xpath/" >XPath</a> oder auch von XPath&nbsp;2.0 nicht aus, um die gewünschten Tests zu formulieren, etwa wenn rekursive Funktionsaufrufe nötig sind. In anderen Situationen möchte man Algorithmen in verschiedenen Tests wiederverwenden. In solchen Situationen helfen benutzerdefinierte Funktionen weiter. Mit <a href="http://blog.expedimentum.com/glossar/xslt/" >XSLT</a>&nbsp;2.0 geht das recht einfach:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;schema</span></span>
<span style="color: #009900;">	<span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://purl.oclc.org/dsdl/schematron&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000066;">xmlns:xsl</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/XSL/Transform&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000066;">queryBinding</span>=<span style="color: #ff0000;">&quot;xslt2&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ns</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;my&quot;</span> <span style="color: #000066;">uri</span>=<span style="color: #ff0000;">&quot;test&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:function</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;my:literal-autor&quot;</span> <span style="color: #000066;">as</span>=<span style="color: #ff0000;">&quot;xs:string?&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:param</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;vorname&quot;</span> <span style="color: #000066;">as</span>=<span style="color: #ff0000;">&quot;xs:string?&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:param</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;nachname&quot;</span> <span style="color: #000066;">as</span>=<span style="color: #ff0000;">&quot;xs:string?&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:sequence</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;concat($nachname, ', ', $vorname)&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:function<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pattern</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;p3&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;rule</span> <span style="color: #000066;">context</span>=<span style="color: #ff0000;">&quot;autor&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;assert</span> <span style="color: #000066;">test</span>=<span style="color: #ff0000;">&quot;my:literal-autor(//person[@xml:id eq current()/@ref]/vorname, //person[@xml:id eq current()/@ref]/nachname) eq .&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>[p3] autor muss eine gültige Kombination aus person/vorname und person/nachname sein.<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/assert<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/rule<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/schema<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Im äußersten <code>schema</code>-Element wird der XSL-Namespace definiert und mit <code>queryBinding="xslt2"</code> XSLT&nbsp;2.0 als Abfragesprache festgelegt. Mit dem <code>ns</code>-Element wird analog zu XSLT&nbsp;2.0 der Namespace für die benutzerdefinierte Funktionen deklariert.</p>
<p>Anschließend folgt die Funktionsdefinition 1:1 wie in XSLT&nbsp;2.0. Das Beispiel fügt Nachname und Vorname – getrennt durch ein Komma – zusammen. <code>xsl:function</code>-Elemente können an beliebiger Position direkt unterhalb von <code>schema</code> stehen.</p>
<p>Schließlich wird im <code>assert</code> die so definierte Funktion verwendet. Das Beispiel testet, ob der Inhalt des <code>autor</code>-Elements mit dem referenzierten <code>person</code>-Element korrespondiert.</p>
<p>Das dazugehörige XML könnte so aussehen:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;literatur<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;buecher<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;buch</span> <span style="color: #000066;">xml:id</span>=<span style="color: #ff0000;">&quot;b1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;autor</span> <span style="color: #000066;">ref</span>=<span style="color: #ff0000;">&quot;p1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Mann, Thomas<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/autor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;titel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Der Zauberberg<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/titel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;isbn<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>978-3-596-29433-6<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/isbn<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;href<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://d-nb.info/942764498<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/href<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/buch<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;buch</span> <span style="color: #000066;">xml:id</span>=<span style="color: #ff0000;">&quot;b2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;autor</span> <span style="color: #000066;">ref</span>=<span style="color: #ff0000;">&quot;p2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Mann,Klaus<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/autor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;titel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Mephisto<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/titel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;isbn<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>3-10-046705-1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/isbn<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;href<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://d nb.info/959653694<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/href<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/buch<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;buch</span> <span style="color: #000066;">xml:id</span>=<span style="color: #ff0000;">&quot;b3&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;autor</span> <span style="color: #000066;">ref</span>=<span style="color: #ff0000;">&quot;b1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/autor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;titel<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/titel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/buch<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/buecher<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;autoren<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;person</span> <span style="color: #000066;">xml:id</span>=<span style="color: #ff0000;">&quot;p1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;vorname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Thomas<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/vorname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;nachname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Mann<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/nachname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;person</span> <span style="color: #000066;">xml:id</span>=<span style="color: #ff0000;">&quot;p2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;vorname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Klaus<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/vorname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;nachname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Mann<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/nachname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/autoren<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/literatur<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p><a href="http://blog.expedimentum.com/wp-content/uploads/oxygenxml_schematron_enable_user_defined_functions.png"><img src="http://blog.expedimentum.com/wp-content/uploads/oxygenxml_schematron_enable_user_defined_functions-300x263.png" alt="OxygenXML-Einstellungsdialog für Schematron" title="OxygenXML: benutzerdefinierte Funktionen für Schematron einschalten" width="300" height="263" class="alignright size-medium wp-image-598" /></a>Bei <code>buch xml:id="b2"</code> wird ein Fehler gemeldet, weil das Leerzeichen nach dem Komma fehlt, bei <code>buch xml:id="b3"</code> wegen des fehlenden Inhaltes. <a href="http://www.expedimentum.org/example/Schematron/buecher-03.sch" title="zur Beispielsammlung">Schema</a> und <a href="http://www.expedimentum.org/example/Schematron/buecher.xml" title="zur Beispielsammlung">XML</a> habe ich in der Beispielsammlung abgelegt.</p>
<p>In <a href="http://blog.expedimentum.com/oxygen/" >OxygenXML</a> muss die Verarbeitung von XSLT innerhalb von <a href="http://blog.expedimentum.com/glossar/schematron/" >Schematron</a> ggfs. erst aktiviert werden. Dazu muss in den Einstellungen unter <code>XML ⇒ XML-Parser</code> ein Häkchen bei <code>ISO Schematron ⇒ Fremde Elemente erlauben (allow-foreign)</code> gesetzt werden, vgl. Bild rechts.</p>
<h3>externe Funktionsbibliotheken</h3>
<p>Oft liegen die benötigten Funktionen bereits in einer Bibliothek vor. Beispielsweise lassen sich URLs mit <code>misc:is-url()</code> aus der <a href="http://code.google.com/p/xslt-sb/" title="XSLT-SB bei Google Code">XSLT-SB</a> auf Gültigkeit testen. Auch das Einbinden externen Bibliotheken geht mit Schematron recht einfach:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;schema</span></span>
<span style="color: #009900;">	<span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://purl.oclc.org/dsdl/schematron&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000066;">xmlns:xsl</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/XSL/Transform&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000066;">queryBinding</span>=<span style="color: #ff0000;">&quot;xslt2&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:include</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;http://www.expedimentum.org/example/xslt/xslt-sb/files.xsl&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ns</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;xsb&quot;</span> <span style="color: #000066;">uri</span>=<span style="color: #ff0000;">&quot;http://www.expedimentum.org/XSLT/SB&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pattern</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;p4&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;rule</span> <span style="color: #000066;">context</span>=<span style="color: #ff0000;">&quot;href&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;assert</span> <span style="color: #000066;">test</span>=<span style="color: #ff0000;">&quot;xsb:is-url(.)&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>[p4] href muss eine gültige URL beinhalten<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/assert<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/rule<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/schema<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Mit diesem Schema wird das <code>href</code>-Element bei <code>buch xml:id="b2"</code> bemängelt, da ein Leerzeichen kein gültiges Zeichen in einer URL ist.</p>
<p>Übrigens hatte ich mit <code>&lt;xsl:import/&gt;</code> keinen Erfolg; mir fällt aber kein Beispiel ein, wo man nicht statt dessen per <code>&lt;xsl:include/&gt;</code> ein (ggfs. angepasstes) externes Stylesheet verwenden könnte. Über Beispiele und/oder Hinweise zur Lösung würde ich mich freuen.</p>
<p>Auch dieses <a href="http://www.expedimentum.org/example/Schematron/buecher-04.sch" title="Schematron in der Beispielsammlung">Schema</a> habe ich in der <a href="http://www.expedimentum.org/example/" title="Beispielsammlung auf www.expedimentum.org">Beispielsammlung</a> abgelegt.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.expedimentum.com/2012/benutzerdefinierte-funktionen-funktionsbibliotheken-schematron/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>xsl:key in Schematron verwenden</title>
		<link>http://blog.expedimentum.com/2012/xsl-key-in-schematron-verwenden/</link>
		<comments>http://blog.expedimentum.com/2012/xsl-key-in-schematron-verwenden/#comments</comments>
		<pubDate>Tue, 01 May 2012 16:45:29 +0000</pubDate>
		<dc:creator>Stf</dc:creator>
				<category><![CDATA[Schematron]]></category>
		<category><![CDATA[XML-Validierung]]></category>
		<category><![CDATA[XSLT und XPath]]></category>

		<guid isPermaLink="false">http://blog.expedimentum.com/?p=556</guid>
		<description><![CDATA[Schlüssel (xsl:key) sind eine Möglichkeit, um Transformationen über größere Dokumente mit vielen (internen oder externen) Verweisen zu beschleunigen. Im Sprachumfang von Schematron sind Daten-Schlüssel nicht enthalten, allerdings ist es sehr einfach, xsl:key zu verwenden. Ein einfaches Beispiel: in einer Literaturliste verweisen die autor-Elemente über das ref-Attribut auf ein korrespondierendes person-Element aus einer Liste: &#60;literatur&#62; &#60;buecher&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>Schlüssel (<code>xsl:key</code>) sind eine Möglichkeit, um Transformationen über größere Dokumente mit vielen (internen oder externen) Verweisen zu beschleunigen. Im Sprachumfang von <a href="http://blog.expedimentum.com/glossar/schematron/" >Schematron</a> sind Daten-Schlüssel nicht enthalten, allerdings ist es sehr einfach, <code>xsl:key</code> zu verwenden. Ein einfaches Beispiel: in einer Literaturliste verweisen die <code>autor</code>-Elemente über das <code>ref</code>-Attribut auf ein korrespondierendes <code>person</code>-Element aus einer Liste:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;literatur<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;buecher<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;buch</span> <span style="color: #000066;">xml:id</span>=<span style="color: #ff0000;">&quot;b1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;autor</span> <span style="color: #000066;">ref</span>=<span style="color: #ff0000;">&quot;p1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Mann, Thomas<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/autor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;titel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Der Zauberberg<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/titel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;isbn<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>978-3-596-29433-6<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/isbn<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;href<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://d-nb.info/942764498<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/href<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/buch<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;buch</span> <span style="color: #000066;">xml:id</span>=<span style="color: #ff0000;">&quot;b2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;autor</span> <span style="color: #000066;">ref</span>=<span style="color: #ff0000;">&quot;p2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Mann,Klaus<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/autor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;titel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Mephisto<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/titel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;isbn<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>3-10-046705-1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/isbn<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;href<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://d nb.info/959653694<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/href<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/buch<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;buch</span> <span style="color: #000066;">xml:id</span>=<span style="color: #ff0000;">&quot;b3&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;autor</span> <span style="color: #000066;">ref</span>=<span style="color: #ff0000;">&quot;b1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/autor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;titel<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/titel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/buch<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/buecher<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;autoren<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;person</span> <span style="color: #000066;">xml:id</span>=<span style="color: #ff0000;">&quot;p1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;vorname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Thomas<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/vorname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;nachname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Mann<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/nachname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;person</span> <span style="color: #000066;">xml:id</span>=<span style="color: #ff0000;">&quot;p2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;vorname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Klaus<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/vorname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;nachname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Mann<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/nachname<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/autoren<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/literatur<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Natürlich lässt sich die Referenz problemlos über <a href="http://blog.expedimentum.com/glossar/xpath/" >XPath</a>-Lokalisierungsschritte wie <code>//person[@xml:id eq current()/@ref]</code> prüfen, aber eleganter und vermutlich schneller geht das mit Schlüsseln. Um <code>xsl:key</code> in Schematron zu verwenden, muss das <code>queryBinding</code> im äußersten <code>schema</code>-Element auf <code>xslt</code> (das ist ohnehin der Standardwert) oder <code>xslt2</code> gesetzt und der XSL-Namespace deklariert werden, danach können <code>xsl:key</code>-Elemente und die <code>key()</code>-Funktion wie in <a href="http://blog.expedimentum.com/glossar/xslt/" >XSLT</a> verwendet werden:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;schema</span></span>
<span style="color: #009900;">	<span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://purl.oclc.org/dsdl/schematron&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000066;">xmlns:xsl</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/XSL/Transform&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000066;">queryBinding</span>=<span style="color: #ff0000;">&quot;xslt&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:key</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;myKey&quot;</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;person&quot;</span> <span style="color: #000066;">use</span>=<span style="color: #ff0000;">&quot;@xml:id&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pattern</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;p3&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;rule</span> <span style="color: #000066;">context</span>=<span style="color: #ff0000;">&quot;autor&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;assert</span> <span style="color: #000066;">test</span>=<span style="color: #ff0000;">&quot;key('myKey', @ref)&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>[p3] autor/@ref muss auf ein person/@xml:id verweisen<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/assert<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/rule<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/schema<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Das <code>assert</code> überprüft, ob jedes <code>autor</code>-Element ein <code>ref</code>-Attribut hat, und ob dieses <code>ref</code>-Attribut auf ein <code>person</code>-Element in der Autorenliste verweist. Entsprechend wird im obigen XML bei <code>buch xml:id="b3"</code> die Referenz auf <code>b1</code> als Fehler gemeldet.</p>
<p><code>xsl:key</code>-Elemente <em>sollen</em> im Schema vor dem ersten <code>pattern</code>-Element stehen. Leider ist der Schematron-Standard diesbezüglich (und wie so oft) nicht sehr präzise; bei einem kurzen Test mit <a href="http://blog.expedimentum.com/oxygen/" >OxygenXML</a> hat aber auch ein <code>xsl:key</code> nach dem <code>pattern</code> funktioniert.</p>
<p><a href="http://www.expedimentum.org/example/Schematron/buecher.xml" title="XML-Beispiel für Schematron">XML-Beispiel</a> und <a href="http://www.expedimentum.org/example/Schematron/buecher-02.sch" title="Beispiel-Schematron">Schematron</a> habe ich in der Beispielsammlung abgelegt.</p>
<h4>Weblink</h4>
<ul>
<li>Dave Pawson, Roger Costello, Florent Georges: ISO Schematron tutorial. <a href="http://www.dpawson.co.uk/schematron/keys.html" title="ISO Schematron tutorial">Using keys for assertions</a> (englisch)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.expedimentum.com/2012/xsl-key-in-schematron-verwenden/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Schematron: Wie werden assert/report, rule, pattern und phase verwendet?</title>
		<link>http://blog.expedimentum.com/2012/schematron-assert-report-rule-pattern-phase/</link>
		<comments>http://blog.expedimentum.com/2012/schematron-assert-report-rule-pattern-phase/#comments</comments>
		<pubDate>Mon, 30 Apr 2012 22:21:58 +0000</pubDate>
		<dc:creator>Stf</dc:creator>
				<category><![CDATA[Grundlagen]]></category>
		<category><![CDATA[Schematron]]></category>
		<category><![CDATA[XML-Validierung]]></category>

		<guid isPermaLink="false">http://blog.expedimentum.com/?p=553</guid>
		<description><![CDATA[Schematron bietet eine differenzierte Logik, um Tests zu organisieren. Dafür werden die hierarchisch organisierten Elemente pattern, rule sowie assert bzw. report verwendet. Mit phase gibt es eine Möglichkeit, einzelne oder mehrere pattern und damit nur Teile des Schemas zur Validierung zu verwenden. Die eigentlichen Tests werden mit assert und report auf der untersten Hierarchiestufe definiert. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.expedimentum.com/glossar/schematron/" >Schematron</a> bietet eine differenzierte Logik, um Tests zu organisieren. Dafür werden die hierarchisch organisierten Elemente <code>pattern</code>, <code>rule</code> sowie <code>assert</code> bzw. <code>report</code> verwendet. Mit <code>phase</code> gibt es eine Möglichkeit, einzelne oder mehrere <code>pattern</code> und damit nur Teile des Schemas zur Validierung zu verwenden.</p>
<p>Die eigentlichen Tests werden mit <code>assert</code> und <code>report</code> auf der untersten Hierarchiestufe definiert. <code>report</code> gibt einen Fehler aus, wenn der Ausdruck im <code>test</code>-Attribute <code>wahr</code> wird, <code>assert</code> hingegen, wenn der Ausdruck nicht erfüllt ist. Außer diesem Unterschied funktionieren beide Elemente exakt gleich; dass es beide gibt, macht Schemata übersichtlicher.</p>
<p><code>assert</code> und <code>report</code> stehen innerhalb von <code>rule</code>. Dieses Element dient hauptsächlich dazu, den Kontext für die enthaltenen <code>assert</code> und <code>report</code> zu bestimmen. <strong>Achtung!</strong> Stehen mehrere <code>rule</code> mit identischem Kontext innerhalb eines <code>pattern</code>, wird nur die erste <code>rule</code> berücksichtigt, weitere <code>rule</code> werden ignoriert. Meist wird man statt mehrerer <code>rule</code> mit identischem Kontext eine <code>rule</code> mit mehreren <code>assert</code> bzw. <code>report</code> verwenden können, falls nicht, müssen getrennte <code>pattern</code> mit diesen <code>rule</code> geschrieben werden.</p>
<p><code>pattern</code> fassen eine oder mehrere <code>rule</code> zusammen. Außerdem dienen sie zur Entkopplung mehrerer <code>rule</code> mit identischem Kontext (s.o.). Eine besondere Bedeutung erlangen sie im Zusammenhang mit <code>phase</code>. Innerhalb von <code>phase</code>-Elementen werden einzelne <code>pattern</code> referenziert und damit verschiedene Validierungsumfänge definiert.</p>
<p>An Hand eines einfachen Beispiels möchte ich das erläutern. In einem Literaturverzeichnis sind Bücher gelistet:</p>

<div class="wp_syntax"><div class="code"><pre class="xnl" style="font-family:monospace;">&lt;literatur&gt;
	&lt;buecher&gt;
		&lt;buch xml:id=&quot;b1&quot;&gt;
			&lt;autor ref=&quot;p1&quot;&gt;Mann, Thomas&lt;/autor&gt;
			&lt;titel&gt;Der Zauberberg&lt;/titel&gt;
		&lt;/buch&gt;
		&lt;buch xml:id=&quot;b3&quot;&gt;
			&lt;autor ref=&quot;b1&quot;&gt;&lt;/autor&gt;
			&lt;titel&gt;&lt;/titel&gt;
		&lt;/buch&gt;
	&lt;/buecher&gt;
&lt;/literatur&gt;</pre></div></div>

<p><code>autor</code>- und <code>titel</code>-Elemente sollen nicht leer sein. Das entsprechende Schema sieht so aus:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;schema</span></span>
<span style="color: #009900;">	<span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://purl.oclc.org/dsdl/schematron&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pattern</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;p1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;rule</span> <span style="color: #000066;">context</span>=<span style="color: #ff0000;">&quot;buch&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;assert</span> <span style="color: #000066;">test</span>=<span style="color: #ff0000;">&quot;normalize-space(autor)&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>[p1] autor darf nicht leer sein<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/assert<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;assert</span> <span style="color: #000066;">test</span>=<span style="color: #ff0000;">&quot;normalize-space(titel)&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>[p1] titel darf nicht leer sein<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/assert<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/rule<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pattern</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;p2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;rule</span> <span style="color: #000066;">context</span>=<span style="color: #ff0000;">&quot;buch&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;assert</span> <span style="color: #000066;">test</span>=<span style="color: #ff0000;">&quot;normalize-space(autor)&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>[p2] autor darf nicht leer sein<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/assert<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/rule<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;rule</span> <span style="color: #000066;">context</span>=<span style="color: #ff0000;">&quot;buch&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;assert</span> <span style="color: #000066;">test</span>=<span style="color: #ff0000;">&quot;normalize-space(titel)&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>[p2] titel darf nicht leer sein<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/assert<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/rule<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;phase</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;phase_1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;active</span> <span style="color: #000066;">pattern</span>=<span style="color: #ff0000;">&quot;p1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;phase</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;phase_2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;active</span> <span style="color: #000066;">pattern</span>=<span style="color: #ff0000;">&quot;p2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/schema<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Schauen wir zuerst auf <code>pattern id="p1"</code>. Im <code>rule</code>-Element wird der Kontext auf alle <code>buch</code>-Elemente gesetzt und dann mit zwei nahezu identischen <code>assert</code> geprüft, ob die Elemente <code>autor</code> und <code>titel</code> Text enthalten (wobei Text, der ausschließlich aus Leerzeichen, Tabs u.ä. – kurz <em>whitespace</em> – besteht, mit <code>normalize-space()</code> entfernt wird).</p>
<p><code>pattern id="p2"</code> demonstriert, dass bei mehreren <code>rule</code> mit identischem Kontext nur das erste <code>rule</code> ausgewertet wird: während bei <code>p1</code> zwei Fehler gemeldet werden (<code>autor</code> und <code>titel</code> ohne Text bei <code>b3</code>), wird von <code>p2</code> nur der erste Fehler gemeldet.</p>
<p><a href="http://blog.expedimentum.com/wp-content/uploads/oxygenxml_schematron_phase-selector.png"><img src="http://blog.expedimentum.com/wp-content/uploads/oxygenxml_schematron_phase-selector.png" alt="Auswahldialog für Phasen in OxygenXML" title="Schematron-Phasen-Auswahl in OxygenXML" width="304" height="289" class="alignright size-full wp-image-583" /></a>Die beiden <code>phase</code>-Elemete demonstrieren, wie man ein Schema logisch aufteilen kann. Per default (und ohne Eintrag im <code>defaultPhase</code>-Attribut im äußersten <code>schema</code>-Element) werden alle <code>pattern</code> validiert. Wenn mit <code>phase</code>-Elementen verschiedene Phasen definiert werden, könne diese getrennt ausgeführt werden. Beispielsweise fragt <a href="http://blog.expedimentum.com/oxygen/" >OxygenXML</a> dann nach, welche Phase validiert werden soll, vgl. Bild rechts.</p>
<p><a href="http://www.expedimentum.org/example/Schematron/buecher.xml" title="XML-Beispiel für Schematron">XML-Beispiel</a> und <a href="http://www.expedimentum.org/example/Schematron/buecher-01.sch" title="Beispiel-Schematron">Schematron</a> sind in der Beispielsammlung abgelegt.</p>
<h4>Weblink</h4>
<ul>
<li>Dave Pawson, Roger Costello, Florent Georges: ISO Schematron tutorial. <a href="http://www.dpawson.co.uk/schematron/start.html" title="ISO Schematron tutorial">Getting Started</a> (englisch)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.expedimentum.com/2012/schematron-assert-report-rule-pattern-phase/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>xsb:random(): Zufallszahlen mit XSLT</title>
		<link>http://blog.expedimentum.com/2012/xsb-random-zufallszahlen-mit-xslt/</link>
		<comments>http://blog.expedimentum.com/2012/xsb-random-zufallszahlen-mit-xslt/#comments</comments>
		<pubDate>Sat, 24 Mar 2012 22:11:07 +0000</pubDate>
		<dc:creator>Stf</dc:creator>
				<category><![CDATA[Grundlagen]]></category>
		<category><![CDATA[XSLT-SB]]></category>

		<guid isPermaLink="false">http://blog.expedimentum.com/?p=489</guid>
		<description><![CDATA[»Der Laie staunt, der Fachmann wundert sich.« Zufallszahlen in XSLT sind soetwas wie die Quadratur des Kreises. Warum? Eine der absoluten Grundlagen funktionaler Programmiersprachen, zu denen auch XPath und XSLT gehören, ist der Verzicht auf Seiteneffekte, d.h. das Ergebnis einer Operation oder Funktion hängt ausschließlich von den übergebenen Parametern ab und nicht von anderen Programmzuständen, [...]]]></description>
			<content:encoded><![CDATA[<p>»Der Laie staunt, der Fachmann wundert sich.« Zufallszahlen in <a href="http://blog.expedimentum.com/glossar/xslt/" >XSLT</a> sind soetwas wie die Quadratur des Kreises. Warum? Eine der absoluten Grundlagen <a href="http://de.wikipedia.org/wiki/Funktionale_Programmierung" title="Wikipedia: Funktionale Programmierung">funktionaler Programmiersprachen</a>, zu denen auch <a href="http://blog.expedimentum.com/glossar/xpath/" >XPath</a> und XSLT gehören, ist der Verzicht auf <a href="http://de.wikipedia.org/wiki/Wirkung_%28Informatik%29" title="Wikipedia: Wirkung (Informatik)">Seiteneffekte</a>, d.h. das Ergebnis einer Operation oder Funktion hängt ausschließlich von den übergebenen Parametern ab und nicht von anderen Programmzuständen, die beispielsweise in Variablen gespeichert und extern verändert werden könnten. Ebenso werden während der Berechnung einer Funktion oder der Ausführung eines Templates keine Programmzustände geändert. Der Vorteil dieser Restriktion ist, dass Programmzustände wesentlich leichter vorhergesagt und damit die Ausführung von Programmen gut optimiert werden können: wenn bspw. einmal <code>log10($input)</code> berechnet wurde, kann der Prozessor beim nächster Auftreten von <code>log10($input)</code> auf das letzte Ergebnis zurückgreifen, weil sich <code>$input</code> per funktionalem Paradigma nicht ändern darf. Daraus folgt, dass eine Funktion <code>random()</code>, die bei jedem Aufruf ein anderes Ergebnis liefert, ein Paradox ist.</p>
<p>XSLT und XPath sind (manchmal zum Verzweifeln) strikt in Bezug auf Seiteneffektfreiheit. Ein Loch im System – das sogar durch den XSLT-Standard gedeckt ist – fand aber <a href="http://www.nesterovsky-bros.com/weblog/2008/11/22/GeneratorFunctionInXslt20.aspx" title="Generator function in xslt 2.0">Vladimir Nesterovsky</a>: <code>generate-id()</code> <a href="http://xsl.markmail.org/thread/plgzdv7h4n5bowvc" title="XSL mailing list: Scope of uniqueness of generate-id()">muss für jeden Knoten eine andere ID liefern; das schließt im Stylesheet generierte temporäre Knoten ein</a>. Eine Funktion, die einen temporären Knoten erzeugt und für diesen <code>generate-id()</code> aufruft, gibt deshalb bei jedem Aufruf ein anderes Ergebnis zurück:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:stylesheet</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;2.0&quot;</span></span>
<span style="color: #009900;">  <span style="color: #000066;">xmlns:f</span>=<span style="color: #ff0000;">&quot;data:,f&quot;</span></span>
<span style="color: #009900;">  <span style="color: #000066;">xmlns:xs</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/2001/XMLSchema&quot;</span></span>
<span style="color: #009900;">  <span style="color: #000066;">xmlns:xsl</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/XSL/Transform&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:template</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;/&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:message</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;</span>
<span style="color: #009900;">    for $i in 1 to 8 return</span>
<span style="color: #009900;">      f:fun()&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:function</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;f:fun&quot;</span> <span style="color: #000066;">as</span>=<span style="color: #ff0000;">&quot;xs:string&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:variable</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;x&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>!<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:variable<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:sequence</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;generate-id($x)&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:function<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:stylesheet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Das Ergebnis mit <a href="http://blog.expedimentum.com/glossar/saxon/" >Saxon</a> ist bspw. <code>tt2 tt3 tt4 tt5 tt6 tt7 tt8 tt9</code>.</p>
<p>Damit kann man nun einen Pseudozufallsszahlengenerator füttern. Ich habe mich für einen <a href="http://de.wikipedia.org/wiki/Kongruenzgenerator#Linearer_Kongruenzgenerator" title="Wikipedia: Linearer Kongruenzgenerator">linearen Kongruenzgenerator</a> entschieden, weil er sich recht einfach implementieren lässt:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:function</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;intern:linear-congruential-generator&quot;</span> <span style="color: #000066;">as</span>=<span style="color: #ff0000;">&quot;xs:integer+&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:param</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;length&quot;</span> <span style="color: #000066;">as</span>=<span style="color: #ff0000;">&quot;xs:integer&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:param</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;vortrag&quot;</span> <span style="color: #000066;">as</span>=<span style="color: #ff0000;">&quot;xs:integer+&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:choose<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:when</span> <span style="color: #000066;">test</span>=<span style="color: #ff0000;">&quot;$length eq 0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:sequence</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;$vortrag[position() gt 1]&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:when<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:otherwise<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:sequence</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;intern:linear-congruential-generator($length - 1, ($vortrag, (1103515245 *$vortrag[last()] + 12345) mod 4294967296) )&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:otherwise<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:choose<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:function<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Die numerischen Konstanten werden so bei der <a href="http://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use" title="en-Wikipedia: Linear congruential generator"><code>glibc</code></a> verwendet, ich habe sie einfach übernommen. Die Funktion ist rekursiv, sie fügt bei jedem Aufruf an die <code>vortrag</code>-Sequenz (die mit einem möglichst zufälligem Startwert – englisch <em>seed</em> – initialisiert wird) eine Pseudozufallszahl an. Der Startwert wird aus der Rückgabe entfernt; so kann man diese Funktion (mit einer <code>length</code> von <code>1</code>) zum einfachen Umwandeln eines Eingabewertes benutzen. <code>intern:linear-congruential-generator(5, 1)</code> ergibt bspw. <code>1103527590 2524885223 662824084 3295386429 4182499122</code>. Dieses Ergebnis ist reproduzierbar, d.h. jeder Aufruf mit den Parametern <code>5, 1</code> liefert genau diese Sequenz zurück.</p>
<p>An diesem Punkt kommt die oben besprochene Funktion zum Erzeugen veränderlicher Werte ins Spiel. Ich habe sie um eine Verarbeitung von Datum und Uhrzeit ergänzt, damit bei jedem Aufruf des Stylesheets neue Pseudozufallswerte erzeugt werden:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:function</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;intern:seed&quot;</span> <span style="color: #000066;">as</span>=<span style="color: #ff0000;">&quot;xs:integer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:param</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;seed&quot;</span> <span style="color: #000066;">as</span>=<span style="color: #ff0000;">&quot;xs:anyAtomicType&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:variable</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;integer-of-seed&quot;</span> <span style="color: #000066;">as</span>=<span style="color: #ff0000;">&quot;xs:integer&quot;</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;if ($seed castable as xs:integer) then xs:integer($seed) else sum(string-to-codepoints(string($seed) ) )&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:variable</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;integer-of-current-date&quot;</span> <span style="color: #000066;">as</span>=<span style="color: #ff0000;">&quot;xs:integer&quot;</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;xs:integer(format-dateTime(current-dateTime(), '[Y][d][H][m][s][f]') )&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:variable</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;temporary_node&quot;</span> <span style="color: #000066;">as</span>=<span style="color: #ff0000;">&quot;text()&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>?<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:variable<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:variable</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;sequence-of-weighted-id-integers&quot;</span> <span style="color: #000066;">as</span>=<span style="color: #ff0000;">&quot;xs:integer+&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:for-each</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;string-to-codepoints(generate-id($temporary_node) )&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:sequence</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;intern:power(xs:integer(10), position()) * xs:integer(.)&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:for-each<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:variable<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:sequence</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;intern:linear-congruential-generator(1, $integer-of-seed + $integer-of-current-date + xs:integer(sum($sequence-of-weighted-id-integers) ) )&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:function<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Disclaimer: Ich bin kein Mathematiker und kann deshalb die Güte der Zufallszahlen nicht beurteilen. Sie eignen sich sicher nicht für kryptographische Anwendungen. Auf der anderen Seite zeigt ein Plot eine recht gleichmäßige Verteilung, so dass sie für die meisten Zwecke ausreichen dürften.</p>
<p>Bei den ersten Tests sahen die Ergebnisse sehr gut aus, aber dann schlug die Optimierung von Saxon zu: <code>for $i in 1 to 100 return string(xsb:random(1))</code> lieferte 100 Mal den selben zufälligen Wert. Die Lösung ist, die Evaluierung der Funktion zu erzwingen, indem als Argument ein möglichst veränderlicher Wert übergeben wird. Das ist hier naheliegend die Zählvariable <code>$i</code>: <code>for $i in 1 to 100 return string(xsb:random($i))</code> liefert wieder recht zufällige Werte. Aus pädagogischen Gründen habe ich deshalb in der <a href="http://blog.expedimentum.com/glossar/xslt-sb/" >XSLT-SB</a> keine <code>xsb:random()</code>-Funktion ohne Argument implementiert. Natürlich könnte ein sehr intelligenter Prozessor auch hier wieder optimieren, aber je schwerer man ihm das macht, umso unwahrscheinlicher ist sein Erfolg.</p>
<h4>siehe auch</h4>
<ul>
<li>Dimitre Novatchev: <a href="http://fxsl.sourceforge.net/articles/Random/Casting%20the%20Dice%20with%20FXSL-htm.htm" title="Dimitre Novatchev: Casting the Dice with FXSL">Casting the Dice with FXSL</a>: Random Number Generation Functions in XSLT (englisch)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.expedimentum.com/2012/xsb-random-zufallszahlen-mit-xslt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Der einfachste REST-Webservice mit XQuery und exist-db (Erste Schritte mit XRX – 2 von X)</title>
		<link>http://blog.expedimentum.com/2011/rest-webservice-mit-xquery-exist-db/</link>
		<comments>http://blog.expedimentum.com/2011/rest-webservice-mit-xquery-exist-db/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 21:51:49 +0000</pubDate>
		<dc:creator>Stf</dc:creator>
				<category><![CDATA[exist-db]]></category>
		<category><![CDATA[XQuery]]></category>
		<category><![CDATA[XRX]]></category>

		<guid isPermaLink="false">http://blog.expedimentum.com/?p=541</guid>
		<description><![CDATA[In einem früheren Beitrag hatte ich mich schon begeistert über die einfachen und eleganten REST-Services, die mit XRX möglich sind, geäußert. Hier nun der Beweis, der einfachste REST-Webservice wo gibt: declare namespace request=&#34;http://exist-db.org/xquery/request&#34;; &#160; &#60;result&#62; {concat('Hallo ', request:get-parameter('name', 'Welt'), '!')} &#60;/result&#62; Dieser Code kann einfach in einer XQuery-Datei innerhalb von exist-db gespeichert werden, in einer [...]]]></description>
			<content:encoded><![CDATA[<p>In einem <a href="http://blog.expedimentum.com/2011/erste-schritte-mit-xrx-1/" title="Erste Schritte mit XRX (1 von X)">früheren Beitrag</a> hatte ich mich schon begeistert über die einfachen und eleganten REST-Services, die mit <a href="http://blog.expedimentum.com/?page_id=505" >XRX</a> möglich sind, geäußert. Hier nun der Beweis, der einfachste REST-Webservice wo gibt:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;">declare namespace request=&quot;http://exist-db.org/xquery/request&quot;;
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;result<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	{concat('Hallo ', request:get-parameter('name', 'Welt'), '!')}
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/result<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Dieser Code kann einfach in einer <a href="http://blog.expedimentum.com/glossar/xquery/" >XQuery</a>-Datei innerhalb von exist-db gespeichert werden, in einer betterFORM-Installation etwa unterhalb des Hauptordners <code>betterform</code>, so dass sie sofort im betterFORM-Dashboard erscheint. Der Service kann dann z.B. mit <code>http://localhost:8080/betterform/rest/db/betterform/service.xquery?name=Max</code> aufgerufen werden, zurückgegeben wird das allseits beliebte »Hallo Max!«. Zugegeben: Das Beispiel macht nicht viel, aber an der Stelle des <a href="http://blog.expedimentum.com/glossar/xpath/" >XPath</a>-Ausdrucks kann natürlich jeder beliebig mächtige andere Ausdruck stehen.</p>
<p>Für die Parameterverarbeitung wird eine <a href="http://exist.sourceforge.net/xquery.html#d2001e934" title="exist-db: xquery">proprietäre Erweiterung von exist-db</a> benutzt; in der Praxis empfiehlt sich deshalb, diese Funktion gegen eine selbst definierte in einer ausgelagerten Modul-Bibliothek zu ersetzen, um bei einem Plattformwechsel schnell die notwendigen Anpassungen vornehmen zu können.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.expedimentum.com/2011/rest-webservice-mit-xquery-exist-db/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XML Schema: complexType mit simpleContent</title>
		<link>http://blog.expedimentum.com/2011/xml-schema-complextype-mit-simplecontent/</link>
		<comments>http://blog.expedimentum.com/2011/xml-schema-complextype-mit-simplecontent/#comments</comments>
		<pubDate>Sun, 04 Dec 2011 12:51:20 +0000</pubDate>
		<dc:creator>Stf</dc:creator>
				<category><![CDATA[Grundlagen]]></category>
		<category><![CDATA[XML Schema]]></category>
		<category><![CDATA[XML-Validierung]]></category>

		<guid isPermaLink="false">http://blog.expedimentum.com/?p=537</guid>
		<description><![CDATA[Gelegentlich steht man vor dem Problem, in XML Schema ein Element mit einem oder mehreren Attributen und einem in irgendeiner Form beschränkten simpleContent (Text, Zahlen, URIs; aber keine Elemente) zu definieren. Die Syntax von XML Schema dazu ist wenig intuitiv: &#60;xs:schema xmlns:xs=&#34;http://www.w3.org/2001/XMLSchema&#34;&#62; &#160; &#60;xs:element name=&#34;MyElement&#34;&#62; &#60;xs:complexType&#62; &#60;xs:simpleContent&#62; &#60;xs:extension base=&#34;MySimpleElementType&#34;&#62; &#60;xs:attribute name=&#34;MyAttribute&#34; type=&#34;MySimpleAttributeType&#34;/&#62; &#60;/xs:extension&#62; &#60;/xs:simpleContent&#62; &#60;/xs:complexType&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>Gelegentlich steht man vor dem Problem, in <a href="http://blog.expedimentum.com/glossar/xml-schema/" >XML Schema</a> ein Element mit einem oder mehreren Attributen und einem in irgendeiner Form beschränkten <code>simpleContent</code> (Text, Zahlen, URIs; aber keine Elemente) zu definieren. Die Syntax von XML Schema dazu ist wenig intuitiv:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:schema</span> <span style="color: #000066;">xmlns:xs</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/2001/XMLSchema&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:element</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;MyElement&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:complexType<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:simpleContent<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:extension</span> <span style="color: #000066;">base</span>=<span style="color: #ff0000;">&quot;MySimpleElementType&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
					<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;MyAttribute&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;MySimpleAttributeType&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xs:extension<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xs:simpleContent<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xs:complexType<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xs:element<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:simpleType</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;MySimpleElementType&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:restriction</span> <span style="color: #000066;">base</span>=<span style="color: #ff0000;">&quot;xs:string&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:enumeration</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;Value_A&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:enumeration</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;Value_B&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xs:restriction<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xs:simpleType<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:simpleType</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;MySimpleAttributeType&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:restriction</span> <span style="color: #000066;">base</span>=<span style="color: #ff0000;">&quot;xs:string&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:enumeration</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;AttributeContent_A&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xs:enumeration</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;AttributeContent_B&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xs:restriction<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xs:simpleType<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xs:schema<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Es handelt sich um einen <code>complexType</code> (wegen des Attributes) mit <code>simpleContent</code> (hier <code>xs:string</code> mit aufgezählten gültigen Werten). Wenig intuitiv ist, dass ein <code>simpleType</code> mit einem Attribut erweitert wird und so faktisch ein <code>complexContent</code> wird, aber trotzdem innerhalb von <code>simpleContent</code> steht. Der Schlüssel ist sicher die Unterscheidung von Type und Content, denn der Inhalt des Elements ist ja immer noch einfach.</p>
<p>Das <a href="http://www.expedimentum.org/example/xsd/complexType_with_simpleContent.xsd" title="XML Schema">Schema</a> und ein <a href="http://www.expedimentum.org/example/xsd/complexType_with_simpleContent.xml" title="XML Instanz">Instanzdokument</a> habe ich in der Beispielsammlung abgelegt.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.expedimentum.com/2011/xml-schema-complextype-mit-simplecontent/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Erste Schritte mit XRX (1 von X)</title>
		<link>http://blog.expedimentum.com/2011/erste-schritte-mit-xrx-1/</link>
		<comments>http://blog.expedimentum.com/2011/erste-schritte-mit-xrx-1/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 00:22:14 +0000</pubDate>
		<dc:creator>Stf</dc:creator>
				<category><![CDATA[exist-db]]></category>
		<category><![CDATA[XForms]]></category>
		<category><![CDATA[XQuery]]></category>
		<category><![CDATA[XRX]]></category>

		<guid isPermaLink="false">http://blog.expedimentum.com/?p=514</guid>
		<description><![CDATA[XRX ist eine Technik für die Entwicklung und den Betrieb von Webanwendungen. Das Akronym steht nach einem sehr allgemeinen Verständnis für XML für die Datenspeicherung im Client, REST-Schnittstellen und XML auf dem Server. Im engeren Sinne wird XRX meist für XForms, REST, XQuery verwendet, wobei XQuery in der Regel auf eine XML-Datenbank zugreift. Als XML-affiner [...]]]></description>
			<content:encoded><![CDATA[<p><strong>XRX</strong> ist eine Technik für die Entwicklung und den Betrieb von Webanwendungen. Das Akronym steht nach einem sehr allgemeinen Verständnis für <em>XML</em> für die Datenspeicherung im Client, <em>REST</em>-Schnittstellen und <em>XML</em> auf dem Server. Im engeren Sinne wird <a href="http://blog.expedimentum.com/?page_id=505" >XRX</a> meist für <em><a href="http://blog.expedimentum.com/?page_id=500" >XForms</a></em>, <em>REST</em>, <em><a href="http://blog.expedimentum.com/glossar/xquery/" >XQuery</a></em> verwendet, wobei XQuery in der Regel auf eine XML-Datenbank zugreift.</p>
<p>Als XML-affiner Zeitgenosse war ich natürlich neugierig auf diese Technik. Meine Erfahrungen bei den ersten Schritten möchte ich hier notieren – schließlich ist aller Anfang schwer, aber nicht notwendigerweise für alle.</p>
<h3>Ein erstes Resümee vorab</h3>
<p>XRX ist recht komplex, und die Entwicklung wird (nach meinem jetzigen Kenntnisstand) nicht mit dem gewohnten Komfort unterstützt. Zuverlässige, d.h. kontext-sensitive Content Completition habe ich bisher noch nicht gefunden, und beim Debugging fühle ich mich schlecht unterstützt: mir fehlen Informationen zu den internen Abläufen (und Fehlern) des XForms-Prozessors. Und gleich noch eine Warnung: ohne einigermaßen belastbare Kenntnisse von <a href="http://blog.expedimentum.com/glossar/xpath/" >XPath</a>, Namespaces und ein bisschen Erfahrung mit <a href="http://blog.expedimentum.com/glossar/xml-schema/" >XML Schema</a>, XQuery und/oder <a href="http://blog.expedimentum.com/glossar/xslt/" >XSLT</a> wird der Einstieg eher schwer.</p>
<p>Auf der anderen Seite wird man von XRX mit eleganter, effizienter und plattformunabhängiger Anwendungsentwicklung belohnt (obwohl ich nicht über genug Erfahrung mit anderen Plattformen verfüge, um solche Einschätzungen zu treffen, wage ich mal dieses Statement). Ein REST-Webservice in drei Zeilen XQuery löst bei mir ebenso Begeisterung aus wie die »magische« (d.h. codefreie) Aktualisierung von Formularfeldern durch XForms oder der unmittelbare Zugriff auf die soeben altualisierten XML-Daten via REST. Da bin ich doch recht zuversichtlich, XRX demnächst auch produktiv einsetzen zu können.</p>
<h3>Installation</h3>
<p>Es gibt verschiedene vorkonfigurierte Bundles aus XForms-Prozessor und XML-Datenbank; ich habe mich aus Bequemlichkeit (die Entwickler arbeiten in Berlin, und ich kenne sie persönlich) für die <a href="http://www.betterform.de/en/xml-suite.html" title="Produktseite von betterFORM">betterFORM XML Suite</a> mit eXist-db als XML-Datenbank entschieden. Für Windows gibt es eine Installer-Exe, für den Mac ein JAR. Unter Windows bemäkelte der Installer das 7er SDK, aber nach einem Neustart lief die Installation einfach durch. betterFORM hat auf seiner Seite eine <a href="http://betterform.wordpress.com/2011/02/24/getting-started-with-betterform-limegreen/" title="Getting started with betterFORM limeGreen">detaillierte Anleitung</a>.</p>
<p>Nach der Installation kann man sich im betterFORM Dashboard einen ersten Eindruck von XForms-Anwendungen verschaffen.</p>
<p><strong>Tipp: </strong>Der »eXist Admin Client« (erreichbar über Download und Start von <code>exist.jnlp</code> rechts oben im betterFORM Dashboard) erlaubt einen ersten Einblick in die Datenbank. Besonders zum Anlegen und Löschen von Collections und Dateien leistet er gute Dienste.</p>
<h3>OxygenXML</h3>
<p>Zum Entwickeln braucht es natürlich eine IDE. <a href="http://blog.expedimentum.com/oxygen/" >OxygenXML</a> bietet eine gute Integration von eXist-db, die Einrichtung ist in der F1-Hilfe und auf der <a href="http://www.oxygenxml.com/eXist_support.html" title="eXist-db bei OxygenXML">OxygenXML-Seite zu eXist-db</a> detailliert beschrieben. Ich habe dann ewig gebraucht, um die URL der REST-Schnittstelle zu finden und bin später über die Lösung gestolpert: beim Start des »eXist Admin Client« ist die korrekte URL voreingestellt und kann einfach nach OxygenXML kopiert werden. Mit den Standardparametern ist die URL <code>xmldb:exist://localhost:8080/betterform/xmlrpc</code>.</p>
<p><a href="http://blog.expedimentum.com/wp-content/uploads/eXist-db_Admin_Client_Login.png"><img src="http://blog.expedimentum.com/wp-content/uploads/eXist-db_Admin_Client_Login-300x197.png" alt="Login-Dialog des »eXist-db Admin Client« mit URL zur RPC-Schnittstelle zur Datenbank" title="»eXist-db Admin Client«, Login" width="300" height="197" class="alignleft size-medium wp-image-517" /></a></p>
<p><a href="http://blog.expedimentum.com/wp-content/uploads/OxygenXML_eXist-db_connector.png"><img src="http://blog.expedimentum.com/wp-content/uploads/OxygenXML_eXist-db_connector-300x201.png" alt="Konfiguration des OxygenXML-Konnektors zu eXist-db" title="OxygenXML, eXist-db connector" width="300" height="201" class="alignright size-medium wp-image-518" /></a></p>
<p><br style="clear:left;"/></p>
<p><strong>Tipp: </strong>Die Arbeit mit Dateien und an der Datenbank geht mit OxygenXML sehr leicht von der Hand. Man kann Dateien öffnen, bearbeiten und zurück in die Datenbank speichern, außerdem sind Dateioperationen wie Löschen, Umbenennen oder Importieren möglich. Unbedingt ausprobieren!</p>
<p><a href="http://blog.expedimentum.com/wp-content/uploads/OxygenXML_Auswahl_Dokumententyp_XForms.png"><img src="http://blog.expedimentum.com/wp-content/uploads/OxygenXML_Auswahl_Dokumententyp_XForms-180x300.png" alt="Auswahl des passenden Dokumententyps bei neuen Dateien" title="OxygenXML, Datei/Neu" width="180" height="300" class="alignright size-medium wp-image-524" /></a>Zweite Hürde ist die Unterstützung durch Content Completition und Validierung. Während XQuery direkt unterstützt wird, ist für XForms etwas Handarbeit notwendig. Der einfachste Weg ist, die Processing Instruction <code>&lt;?xml-model href="http://www.oxygenxml.com/1999/xhtml/xhtml-xforms.nvdl" schematypens="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0"?&gt;</code> am Anfang eines XHTML-Dokumentes einzufügen. Außerdem können neue Dokumente über Datei/Neu mit dem Dokumenentyp (unter Framework templates/XHTML) »XHTML 1.0 RNG Based + XForms 1.1« angelegt werden. Die XForms-Unterstützung ist nicht perfekt, aber sehr praktisch.</p>
<h3>»Hello World« und Tutorials</h3>
<p>Das <a href="http://en.wikibooks.org/wiki/XForms/HelloWorld" title="Hello World im Wikibook »XForms«">Hello-World-Beispiel</a> aus dem XForms-Wikibook lief bei mir auf Anhieb. Die nächsten Schritte – Zugriff auf eXist-db, Anzeigen, Erstellen, Löschen, Laden und Speichern von Datensätzen – habe ich mir recht zügig mit dem guten »<a href="http://wiki.orbeon.com/forms/doc/developer-guide/orbeon-forms-xforms-tutorial" title="Orbeon Forms XForms Tutorial">Orbeon Forms XForms Tutorial</a>« erarbeitet. Danach helfen der <a href="http://www.w3.org/TR/xforms/" title="W3C recommendation XForms 1.1">XForms-Standard beim W3C</a>, der »XForms Feature Explorer« (erreichbar über das betterFORM Dashboard) sowie die <a href="http://exist.sourceforge.net/documentation.html" title="eXist-db, Dokumentation">Online-Dokumentation von eXist-db</a> weiter. Schließlich habe ich mir manche Einsicht und Anregung aus »<a href="http://www.danmccreary.com/xrx/beginners-guide/beginners-guide-to-xrx.xhtml" title="A Beginners Guide [to] XRX">A Beginners Guide XRX</a>« von Dan McCreary und Joe Wicentowski geholt.</p>
<p>Im Rückblick war der Einstieg dann gar nicht so schwer. Größte und unerwartete Hürde für mich war das Erforschen und Verstehen des Model-View-Controller-Konzepts von XForms und der darauf aufbauenden Sprachkonstrukte. Und auch ein paar Pattern wollten erarbeitet sein. Dazu vielleicht später mehr.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.expedimentum.com/2011/erste-schritte-mit-xrx-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XSLT-SB: asin(), acos(), atan(), atan2(), dynamische Typung</title>
		<link>http://blog.expedimentum.com/2011/xslt-sb-asin-acos-atan-atan2-dynamische-typung/</link>
		<comments>http://blog.expedimentum.com/2011/xslt-sb-asin-acos-atan-atan2-dynamische-typung/#comments</comments>
		<pubDate>Sun, 26 Jun 2011 23:06:29 +0000</pubDate>
		<dc:creator>Stf</dc:creator>
				<category><![CDATA[Allgemeines]]></category>
		<category><![CDATA[XSLT-SB]]></category>

		<guid isPermaLink="false">http://blog.expedimentum.com/?p=475</guid>
		<description><![CDATA[Mit dem Sprung auf Version 0.2.37 kann die XSLT-SB, genauer math.xsl, jetzt auch die Arkusfunktionen und dynamische Typung. In Ergänzung der knappen Release-Notes hier ein paar Anmerkungen dazu. Arkusfunktionen Die Gruppe der Arkusfunktion lässt sich einfach auf der Grundlage von atan() implementieren – wenn man den richtigen Ansatz gefunden hat. Meine ersten Versuche, asin() und [...]]]></description>
			<content:encoded><![CDATA[<p>Mit dem Sprung auf Version 0.2.37 kann die <a href="http://code.google.com/p/xslt-sb/">XSLT-SB</a>, genauer <a href="http://www.expedimentum.org/example/xslt/xslt-sb/math.xsl"><code>math.xsl</code></a>, jetzt auch die Arkusfunktionen und dynamische Typung. In Ergänzung der knappen Release-Notes hier ein paar Anmerkungen dazu.</p>
<h3>Arkusfunktionen</h3>
<p>Die Gruppe der Arkusfunktion lässt sich einfach auf der Grundlage von <code>atan()</code> implementieren – wenn man den richtigen Ansatz gefunden hat. Meine ersten Versuche, <code>asin()</code> und <code>atan()</code> über <a href="http://de.wikipedia.org/wiki/Taylorreihe#Trigonometrische_Funktionen">Taylor-Reihen</a> zu implementierten scheiterten daran, dass diese Reihen zu langsam konvergieren. Zusammen mit den in der Reihenbildung verwendeten rekursiven Funktionen (Fakultät und Potenz) war schnell das Limit der Rekursionstiefe erreicht: <a href="http://blog.expedimentum.com/glossar/saxon/" >Saxon</a> bricht die Verarbeitung mit Hinweis auf das Überschreiten der maximalen Rekursionstiefe ab.</p>
<p>Die Lösung brachte ein alternativer Algorithmus zur Berechnung von <code>atan()</code>, den ich bei <a href="http://mathworld.wolfram.com/InverseTangent.html">WolframMathWorld</a> fand (Gleichungen Nr.&nbsp;44 bis 48). Mittels des Arkustangens lässt sich einfach der Arkussinus und Arkuskosinus berechnen, so dass diese Implementierung ein Kinderspiel war (siehe <a href="http://de.wikipedia.org/wiki/Arkussinus_und_Arkuskosinus#Beziehung_zum_Arkustangens">Wikipedia</a>).</p>
<h3>dynamische Typung</h3>
<p>Zweites großes Thema der Überarbeitung von <code>math.xsl</code> war die dynamische Typung. Die mathematischen Operatoren und Funktionen in <a href="http://blog.expedimentum.com/glossar/xpath/" >XPath</a> geben ihr Ergebnis i.d.R. mit dem Typ der Argumente zurück. Zum Beispiel ist das Ergebnis von <code>fn:round-half-to-even()</code> mit einem Argument vom Typ <code>xs:decimal</code> vom Typ <code>xs:decimal</code>, während mit einem <code>xs:double</code>-Argument das Ergebnis vom Typ <code>xs:double</code> ist.</p>
<p>Die Implementierung dieses Verhaltens barg einige Schwierigkeiten, weil manche Funktionen als Ergebnis <code>NaN</code>, <code>-INF</code> oder <code>INF</code> zurückgeben können. Diese speziellen Werte sind zwar mit den Typen <code>xs:float</code> und <code>xs:double</code> darstellbar, nicht aber mit <code>xs:decimal</code> (das aber genauere Ergebnisse als<code> xs:double</code> liefert) und <code>xs:integer</code>. Das gewünschte Verhalten ist wohl sehr vom Einsatzzweck der Funktionen abhängig. Der jetzige Kompromiss ist daher, dass bei diesen Werten der Cast von <code>NaN</code>, <code>-INF</code> oder <code>INF</code> auf ungeeignete Typen scheitert; wer Wert auf hohe Genauigkeit legt, kann vielleicht auch die kritischen Werte umschiffen.</p>
<h3>Genauigkeit</h3>
<p>Laut <a href="http://www.w3.org/TR/xmlschema-2/#decimal">Standard</a> müssen XPath-Implementierungen mit 18 signifikanten Stellen rechnen. Für die <a href="http://blog.expedimentum.com/glossar/xslt-sb/" >XSLT-SB</a> habe ich mittels <code>intern:round()</code> die Genauigkeit auf 16 Stellen begrenzt, weil damit die meisten Tests erfolgreich absolviert werden. Trotzdem wird für manche Testwerte (etwa <code>exp(100)</code>) nicht das richtige Ergebnis ermittelt (bei vielen Berechnungsschritten summieren sich die Fehler halt). In diesen Fällen wird im Testprotokoll (hier z.B. für <a href="http://www.expedimentum.org/example/xslt/xslt-sb/test-results/saxon-ee/math_tests.html">Saxon&nbsp;EE</a>) eine Warnung (orange hinterlegt) ausgegeben. Diese sind zu unterscheiden von den gelb hinterlegten Fällen, bei denen ein Cast der Ergebnisse auf <code>xs:decimal</code> (den Typ der Tests) nicht möglich ist, siehe oben. In den Tests nicht berücksichtigt sind die Fälle, für die eine Funktion nicht definiert ist, etwa <code>asin(3)</code>.</p>
<p>Intern (d.h. bei den Funktionen mit <code>intern:</code>-Prefix) wird mit einer höhren Stellenzahl gerechnet, diese müssen aber weder signifikant noch richtig sein.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.expedimentum.com/2011/xslt-sb-asin-acos-atan-atan2-dynamische-typung/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AltovaXML in OxygenXML einbinden</title>
		<link>http://blog.expedimentum.com/2011/altovaxml-in-oxygenxml-einbinden/</link>
		<comments>http://blog.expedimentum.com/2011/altovaxml-in-oxygenxml-einbinden/#comments</comments>
		<pubDate>Mon, 30 May 2011 05:24:20 +0000</pubDate>
		<dc:creator>Stf</dc:creator>
				<category><![CDATA[Allgemeines]]></category>
		<category><![CDATA[Grundlagen]]></category>

		<guid isPermaLink="false">http://blog.expedimentum.com/?p=395</guid>
		<description><![CDATA[Um AltovaXML in OxygenXML nutzen zu können, muss man diesen XSLT-Prozessor als »Custom Engine« einrichten. So geht’s: Unter Einstellungen/XML/XSLT-FO-XQuery/Custom Engines einen neuen Prozessor anlegen: Als Prozessortyp ist »XSLT« vorausgewählt und richtig. Name und Beschreibung eingeben und dann in das Feld Kommandozeile »"C:\Program Files (x86)\Altova\AltovaXML2011\AltovaXML.exe" /xslt2 ${xsl} /in ${xml} /out ${out}« eintragen (Pfad zu AltovaXML bitte [...]]]></description>
			<content:encoded><![CDATA[<p>Um <a href="http://blog.expedimentum.com/glossar/altovaxml/" >AltovaXML</a> in <a href="http://blog.expedimentum.com/oxygen/" >OxygenXML</a> nutzen zu können, muss man diesen <a href="http://blog.expedimentum.com/glossar/xslt-prozessor/" >XSLT-Prozessor</a> als »Custom Engine« einrichten. So geht’s:</p>
<p>Unter <code>Einstellungen/XML/XSLT-FO-XQuery/Custom Engines</code> einen neuen Prozessor anlegen:</p>
<div id="attachment_397" class="wp-caption aligncenter" style="width:500px"><a href="http://blog.expedimentum.com/2011/altovaxml-in-oxygenxml-einbinden/OxygenXML_Altova_01/"><img src="http://blog.expedimentum.com/wp-content/uploads/OxygenXML_Altova_01.png" alt="OxygenXML: einen neuen XSLT-Prozessor anlegen, Seite »Custom Engines«" title="OxygenXML_Altova_01" width="500" class="size-medium wp-image-397" /></a></div>
<p/>
<p>Als Prozessortyp ist »XSLT« vorausgewählt und richtig. Name und Beschreibung eingeben und dann in das Feld Kommandozeile »<code>"C:\Program Files (x86)\Altova\AltovaXML2011\AltovaXML.exe" /xslt2 ${xsl} /in ${xml} /out ${out}</code>« eintragen (Pfad zu AltovaXML bitte an lokale Gegebenheiten anpassen).</p>
<div id="attachment_398" class="wp-caption aligncenter" style="width: 374px"><a href="http://blog.expedimentum.com/2011/altovaxml-in-oxygenxml-einbinden/OxygenXML_Altova_02/"><img src="http://blog.expedimentum.com/wp-content/uploads/OxygenXML_Altova_02.png" alt="OxygenXML: einen neuen XSLT-Prozessor anlegen: Standardeinstellung für AltovaXML" title="OxygenXML_Altova_02" width="364" height="491" class="size-full wp-image-398" /></a><p class="wp-caption-text">OxygenXML: Standardeinstellung für AltovaXML</p></div>
<p>Speichern, fertig. In den Transformationsszenarien kann jetzt der neu angelegte Prozessor ausgewählt werden:</p>
<div id="attachment_397" class="wp-caption aligncenter" style="width:526px"><a href="http://blog.expedimentum.com/2011/altovaxml-in-oxygenxml-einbinden/OxygenXML_Altova_04/"><img src="http://blog.expedimentum.com/wp-content/uploads/OxygenXML_Altova_04.png" alt="OxygenXML: Auswahl der XSLT-Prozessors im Transformationsszenario" title="OxygenXML_Altova_04" width="526" height="414" class="size-full wp-image-400" /></a></div>
<p/>
<p>Leider kann OxygenXML keine Parameter oder initiale Modes bzw. initiale Templates an den so erzeugten Prozessor übergeben. Ein Workaround ist, für definierte Fälle eigene Prozessoren anzulegen. Für den ad-hoc-Selbsttest der XSL-SB sieht das so aus:</p>
<div id="attachment_399" class="wp-caption aligncenter" style="width: 374px"><a href="http://blog.expedimentum.com/2011/altovaxml-in-oxygenxml-einbinden/OxygenXML_Altova_03/"><img src="http://blog.expedimentum.com/wp-content/uploads/OxygenXML_Altova_03.png" alt="OxygenXML: einen neuen XSLT-Prozessor anlegen: AltovaXML mit erweiterten Einstellungen für initialen Mode und Parameter" title="OxygenXML_Altova_03" width="364" height="491" class="size-full wp-image-399" /></a><p class="wp-caption-text">OxygenXML: AltovaXML mit erweiterten Einstellungen für initialen Mode und Parameter</p></div>
<p>Der erste Teil der Kommandozeile »<code>"C:\Program Files (x86)\Altova\AltovaXML2011\AltovaXML.exe" /xslt2 ${xsl} /in ${xml} /out ${out} /m internals.self-test -param internals.logging-level="'DEBUG'" -param internals.errors.die-on-critical-errors="'no'"</code>« ist identisch zu oben, initialer Mode und Parameter werden zusätzlich hart codiert übergeben. Hier sollten die Entwickler von OxygenXML gelegentlich einmal nachbessern, es kann ja nicht so schwer sein, einen benannten Parameter als benanntes Makro anzubieten.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.expedimentum.com/2011/altovaxml-in-oxygenxml-einbinden/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XSLT-SB – eine Standard-Bibliothek für XSLT</title>
		<link>http://blog.expedimentum.com/2011/xslt-sb-standard-bibliothek-fuer-xslt/</link>
		<comments>http://blog.expedimentum.com/2011/xslt-sb-standard-bibliothek-fuer-xslt/#comments</comments>
		<pubDate>Sat, 14 May 2011 21:45:40 +0000</pubDate>
		<dc:creator>Stf</dc:creator>
				<category><![CDATA[Beispiele]]></category>
		<category><![CDATA[XSLT und XPath]]></category>
		<category><![CDATA[XSLT-SB]]></category>

		<guid isPermaLink="false">http://blog.expedimentum.com/?p=367</guid>
		<description><![CDATA[Es ist vollbracht. Nach ein paar Wochenenden mit Feinschliff und letzten Test habe ich Version 0.2 von XSLT-SB – einer Standard-Bibliothek für XSLT – veröffentlicht. Was ist XSLT-SB? Die XSLT-Standard-Bibliothek (XSLT-SB) beinhaltet nützliche, immer wieder gebrauchte Funktionen und Templates. Gleichzeitig dient sie als beispielhafte Implementierung bestimmter Techniken. Sie wendet sich als Beispielsammlung vor allem an [...]]]></description>
			<content:encoded><![CDATA[<p>Es ist vollbracht. Nach ein paar Wochenenden mit Feinschliff und letzten Test habe ich Version 0.2 von <a href="http://blog.expedimentum.com/glossar/xslt-sb/" >XSLT-SB</a> – einer Standard-Bibliothek für <a href="http://blog.expedimentum.com/glossar/xslt/" >XSLT</a> – veröffentlicht.</p>
<h3>Was ist XSLT-SB?</h3>
<p>Die XSLT-Standard-Bibliothek (XSLT-SB) beinhaltet nützliche, immer wieder gebrauchte Funktionen und Templates. Gleichzeitig dient sie als beispielhafte Implementierung bestimmter Techniken. Sie wendet sich als Beispielsammlung vor allem an deutschsprachige Entwickler, um für diese die Einstiegshürden zu senken.</p>
<p>Die XSLT-SB hat zwei Quellen: einerseits habe ich zeitig angefangen, immer wieder gebrauchte Funktionen und Templates in produktive Bibliothek-Stylesheets auszulagern. Für die XSLT-SB habe ich einige davon übernommen. Beispiele dafür sind <code>xsb:force-cast-to-integer()</code> und <code>xsb:parse-string-to-boolean()</code> sowie die Grundlagen des Logging-Systems. Andererseits habe ich aus Spaß (oder so) mal die eine oder andere Funktion implementiert, bspw. ist <code><a href="http://www.expedimentum.org/example/xslt/xslt-sb/files.xsl">files.xsl</a></code> wesentlich umfangreicher ausgefallen, als es für die eigentliche Aufgabe notwendig gewesen wäre.</p>
<p>Templates und Funktionen der XSLT-SB entstanden also nicht systematisch, sondern nach Bedarf oder Interesse. Im besonderen habe ich nicht versucht, bestehende Bibliotheken wie <a href="http://blog.expedimentum.com/glossar/exslt/" >EXSLT</a> zu ersetzen. Deshalb kann die XSLT-SB mit Fug und Recht als lückenhaft bezeichnet werden.</p>
<p>Ich habe die XSLT-SB in einigen kleineren Projekten produktiv eingesetzt, aber der dauernde Härtetest steht noch aus. Außerdem sind die Stylesheets durch Dokumentation und Tests recht umfangreich; und ich habe sie auch nicht auf eine hohe Ausführungsgeschwindigkeit optimiert. Deshalb möchte ich heute von einem produktiven Einsatz abraten, aber selbstverständlich können einzelne Templates oder Funktionen gezielt in eigene Projekte übernommen werden. Die Veröffentlichung der Stylesheets macht einen breiteren Einsatz möglich, und ich freue mich auf das Feedback. Abhängig davon mag sie sich in die eine oder andere Richtung entwickeln &#8211; mehr Beispielsammlung oder mehr produktive Bibliothek.</p>
<p>Drei Besonderheiten der XSLT-SB möchte ich hervorheben: <code>files.xsl</code>, das Logging-System und die Testumgebung.</p>
<h3>files.xsl</h3>
<p><code>files.xsl</code> bündelt Funktionen rund um URLs. Da <code>xs:anyURI</code> kaum geprüft wird, habe ich die Regeln von <a href="http://tools.ietf.org/html/rfc1808">RFC 1808</a> (URL) in diverse String-Tests gegossen und darauf aufbauend Funktionen zum Ermitteln von Dateiname, Dateipfad, Dateierweiterung usw. entwickelt. Ergänzt wird das Stylesheet durch Funktionen wie <code>xsb:file-exists()</code> und <code>xsb:mediatype-from-url()</code>.</p>
<p>Das Stylesheet demonstriert einige spezielle XML- und XSLT-Techniken, etwa benannte Entities für lesbare <a href="http://blog.expedimentum.com/glossar/regularer-ausdruck/" >reguläre Ausdrücke</a>, von Systemeigenschaften abhängige Funktionen (mit <code>use-when</code>) und die Verwendung von Java-Funktionen.</p>
<h3>Logging-System</h3>
<p>Die XSLT-SB implementiert ein konfigurierbares Logging-System, um Nachrichten des Stylesheets während der Verarbeitung einfach und flexibel auszugeben. Meldungen können per <code>xsl:message</code> oder (soweit der Rückgabetyp einer Funktion oder eines Templates das zulässt) als Kommentar, XML-Element oder HTML ausgegeben werden, unterschiedliche Dringlichkeitsstufen werden unterstützt. Die XSLT-SB nutzt das Logging-System intensiv für die Selbsttests der Funktionen, für den Einstieg lohnt ein Blick auf <code>xsb:internals.Error</code> bzw. <code>xsb:internals.FunctionError</code> in <a href="http://www.expedimentum.org/example/xslt/xslt-sb/internals.xsl">internals.xsl</a>.</p>
<h3>Testumgebung</h3>
<p>Für Funktionstest habe ich eine Testumgebung entwickelt (siehe <a href="http://www.expedimentum.org/example/xslt/xslt-sb/internals.testing.xsl">internals.testing.xsl</a>). Tests werden in Templates zusammengefasst, die im Stylesheet selbst oder in externen Teststylesheets abgelegt werden können und per initialem Mode oder initialem Template aufgerufen werden. Einige Funktionen und Templates helfen beim Vergleich von erwarteten und berechneten Werten und kümmern sich um die Protokollierung. Interessanterweise haben mir die Test nicht nur beim nachträglichen Absichern der Stylesheets geholfen, sondern ich bin relativ schnell auf eine testgetriebene Entwicklung umgestiegen. Diesen Aspekt möchte ich in meiner täglichen Arbeit nicht mehr missen.</p>
<p>Die Testumgebung wird durch formale Tests der Stylesheets selbst ergänzt (<a href="http://www.expedimentum.org/example/xslt/xslt-sb/internals.stylecheck.xsl">internals.stylecheck.xsl</a>, Template <code>intern:internals.Stylecheck</code>). Sie warnen bei fehlender Typung von Variablen, Parametern und Funktionen, fehlender Dokumentation u.a. und listen ToDos.</p>
<p>Ein Beispiel für absolvierte Tests und den Stylecheck, ausgegeben über das Logging-System als HTML, sind die <a href="http://www.expedimentum.org/example/xslt/xslt-sb/test-results/saxon-he/files_tests.html">Testergebnisse für <code>files.xml</code> unter Saxon-HE</a>.</p>
<h3>Wie kann die XSLT-SB benutzt werden?</h3>
<p>Wie ich oben schrieb, kann ich die XSLT-SB im Moment nicht für den produktiven Einsatz empfehlen. Wer es trotzdem wagen möchte, kann sich die Stylesheets <a href="http://code.google.com/p/xslt-sb/downloads/list">herunterladen</a> und in eigene Projekte einbinden. Ein neues Projekt kann einfach auf der Grundlage von <a href="http://www.expedimentum.org/example/xslt/xslt-sb/pattern+includes.xsl">pattern+includes.xsl</a> begonnen werden. Natürlich kann man die Stylesheets auch zum Nachschauen oder für Kopieren &#038; Einfügen verwenden.</p>
<p>Die Verwendung der meisten Funktionen sollte selbsterklärend sein, für die Logging- und Testumgebung können die XSLT-SB-Stylesheets als Beispiel herangezogen werden. Die Stylesheets sind dokumentiert; eine HTML-Version der Dokumentation liegt im <code>doc</code>-Verzeichnis der Distribution und – meist aktueller – <a href="http://www.expedimentum.org/example/xslt/xslt-sb/doc/">online</a>.</p>
<h3>Lizenz</h3>
<p>Die Stylesheets und das Drumherum sind dual lizenziert: EXPAT (MIT) für den Einsatz als Software und CC-by&#160;3.0, so dass einer Verwendung keine rechtlichen Hürden im Weg stehen sollten.</p>
<h3>Was kommt als nächstes?</h3>
<p>Das hängt vom Feedback ab – oder von überraschenden neuen Projekten. Auszug aus meiner ToDo-List:</p>
<ul>
<li><s>auf Intel SOAE zum laufen bringen, im Moment stürzt dieser Prozessor einfach ab</s> [<strong>Nachtrag:</strong> Ich habe das Problem eingegrenzt und im Intel-Forum dargestellt. In neueren Versionen des Prozessors tritt es wohl nicht mehr auf, allerdings plant Intel keine Veröffentlichung einer neuen Version, siehe <a href="http://software.intel.com/en-us/forums/showthread.php?t=82906&#038;o=a&#038;s=lr">hier</a>. Damit sind mir hier wohl die Hände gebunden …]</li>
<li>Dokumentation verbessern, z.B. Liste der Funktionen mit Kurzbeschreibung erstellen. [<strong>Nachtrag:</strong> Im <a href="http://code.google.com/p/xslt-sb/w/list">Projektwiki</a> gibt es jetzt aus den Stylesheets heraus generierte Übersichten.]</li>
<li>zusätzliche Funktionen implementieren, bspw. habe ich gerade wieder mal das <code>p:directory-list</code> aus <a href="http://blog.expedimentum.com/glossar/xproc/" >XProc</a> vermisst</li>
<li>Kompakt-Distribution ohne geschwätzige Kommentare und Dokumentation erzeugen, um die Startgeschwindigkeit zu erhöhen</ul>
<h3>Links</h3>
<p>Ich habe das Projekt bei Google-Code eingestellt, dort gibt es sowohl ein SVN-Repository als auch fertige Distributionen, die gelegentlich dem aktuellen Entwicklungsstand hinterherhinken können. Auf den Expedimentum-Seiten gibt es ein aktuelles Checkout aus dem Trunk, hier kann man auch online die Dokumentation einsehen. Kommentare und Fehlermeldungen sollten über die Google-Seiten laufen.</p>
<ul>
<li><strong>Download:</strong> <a href="http://code.google.com/p/xslt-sb/downloads/list">http://code.google.com/p/xslt-sb/downloads/list</a></li>
<li><strong>Projektseite bei Google Code:</strong> <a href="http://code.google.com/p/xslt-sb/">http://code.google.com/p/xslt-sb/</a></li>
<li><strong>aktuelles Checkout:</strong> <a href="http://www.expedimentum.org/example/xslt/xslt-sb/">http://www.expedimentum.org/example/xslt/xslt-sb/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.expedimentum.com/2011/xslt-sb-standard-bibliothek-fuer-xslt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

