Home
Über mich
Blog
Veröffentlichungen
IT-Trainings
Impressum


XProc

XProc

XProc bietet komfortable Möglichkeiten, ganze Konvertierungsstrecken bedingungsgesteuert samt Validierungen zu definieren. Dabei kann sowohl XSLT als auch XQuery zum Einstz kommen.

pic/xproc.png

Das folgende Xproc-Script

<?xml version="1.0" encoding="UTF-8"?> 
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" 
  xmlns:c="http://www.w3.org/ns/xproc-step" version="1.0"> 
  <p:input port="source" sequence="true"/> 
  <p:input port="parameters" kind="parameter"/>
  <p:output port="result" sequence="true"/> 
  <p:validate-with-xml-schema>
    <p:input port="schema">
      <p:document href="Ort_Elemente.xsd"/>
    </p:input>
  </p:validate-with-xml-schema>
  <p:xslt> 
    <p:input port="stylesheet"> 
      <p:document href="p3_XML2XML_2Gruppen.xsl"/> 
    </p:input> 
  </p:xslt> 
  <p:validate-with-xml-schema>
    <p:input port="schema">
      <p:document href="ZweiGruppen.xsd"/>
    </p:input>
  </p:validate-with-xml-schema>
  <p:xquery>
    <p:input port="query">
      <p:data href="wgqu1.xquery"/>
    </p:input>
  </p:xquery>
  <p:xquery>
    <p:input port="query">
      <p:data href="wgqu_E2A.xquery"/>
    </p:input>
  </p:xquery>
</p:declare-step> 

Nach der Validierung des ursprünglichen Inputs startet "p3_XML2XML_2Gruppen.xsl" mit der ersten Transformation.

<xsl:stylesheet version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" version="1.0" 
      encoding="UTF-8" indent="yes"/>
 <xsl:template match="/">
  <Root>
   <A>
    <xsl:for-each 
         select="/Orte/Ort/Mensch[Gehalt &gt;= sum(Kauf/Gesamt)]">      
     <xsl:call-template name="shPerson"/>
    </xsl:for-each>
   </A>
   <B>
    <xsl:for-each 
         select="/Orte/Ort/Mensch[Gehalt &lt; sum(Kauf/Gesamt)]">      
     <xsl:call-template name="shPerson"/>
    </xsl:for-each>
   </B>
  </Root>
 </xsl:template> 
 <xsl:template name="shPerson">
  <Person>
   <Nr><xsl:value-of select="position()"/></Nr>
   <NN><xsl:value-of select="name"/></NN>
   <VN><xsl:value-of select="vorname"/></VN>
   <WO><xsl:value-of select="../name"/></WO>
   <EK><xsl:value-of select="Gehalt"/></EK>
   <AG><xsl:value-of select="sum(Kauf/Gesamt)"/></AG>
  </Person>
 </xsl:template>
</xsl:stylesheet>

Das Ergebnis dieser XSL-Transformation (also das erste Zwischenergebnis der Konvertierungsstrecke) ist (kurz gefasst):

<Root>
 <A>
  <Person>
   <Nr>1</Nr>
   <NN>Nixlos</NN>
   <VN>Nicole</VN>
   <WO>Neustadt</WO>
   <EK>1234.56</EK>
   <AG>961.6300000000001</AG>
  </Person>
 </A>
 <B>
  <Person>
   <Nr>1</Nr>
   <NN>Holzflos</NN>
   <VN>Hugo</VN>
   <WO>Neustadt</WO>
   <EK>234.56</EK>
   <AG>3563.1400000000003</AG>
  </Person>
  <Person>
   <Nr>4</Nr>
   <NN>Rhodos</NN>
   <VN>Rudi</VN>
   <WO>Darmstadt</WO>
   <EK>333.33</EK>
   <AG>740.6999999999999</AG>
  </Person>
  <Person>
   <Nr>5</Nr>
   <NN>Schlaflos</NN>
   <VN>Susi</VN>
   <WO>Kapstadt</WO>
   <EK>321</EK>
   <AG>808.13</AG>
  </Person>
  <Person>
   <Nr>7</Nr>
   <NN>Leinenlos</NN>
   <VN>Liane</VN>
   <WO>Kapstadt</WO>
   <EK>135</EK>
   <AG>964.0699999999999</AG>
  </Person>
 </B>
</Root>

Im nächsten Schritt wird dieses Ergebnis gegen ein XML Schema validiert. Wenn hier kein Fehler auftaucht, übernimmt das externe XQuery-Script "wgqu1.xquery" das vorige Zwischenergebnis als XML Input und verarbeitet es weiter, indem es alle Personen aus der Gruppe B herausfiltert, deren Ausgaben größer sind als die Einnahmen:

<erg>
{
  for $m in /Root/B/Person
  where $m/AG > $m/EK 
  return 
    <Problem EK="{$m/EK/text()}" 
             AG="{$m/AG/text()}">
      <Vorname>{$m/VN/text()}</Vorname>
      <Nachname>{$m/NN/text()}</Nachname>
      <Stadt>{$m/WO/text()}</Stadt>
    </Problem>
}
</erg>

Das Ergebnis dieser XQuery-basierten Transformation ist dann:

<erg>
  <Problem EK="234.56" AG="3563.1400000000003">
    <Vorname>Hugo</Vorname>
    <Nachname>Holzflos</Nachname>
    <Stadt>Neustadt</Stadt>
  </Problem>
  <Problem EK="333.33" AG="740.6999999999999">
    <Vorname>Rudi</Vorname>
    <Nachname>Rhodos</Nachname>
    <Stadt>Darmstadt</Stadt>
  </Problem>
  <Problem EK="321" AG="808.13">
    <Vorname>Susi</Vorname>
    <Nachname>Schlaflos</Nachname>
    <Stadt>Kapstadt</Stadt>
  </Problem>
  <Problem EK="135" AG="964.0699999999999">
    <Vorname>Liane</Vorname>
    <Nachname>Leinenlos</Nachname>
    <Stadt>Kapstadt</Stadt>
  </Problem>
</erg>

Das externe XQuery-Script "wgqu_E2A.xquery" nimmt den XML Input aus der vorherigen XQuery-Transformation entgegen und verarbeitet ihn weiter, indem es

<ERGEBNIS>
{
  (: definiert die ganze Sequenz :)
  let $root := /erg/Problem 
  (: Vorsortierung loop ueber die Sequenz in tempvar :)
  let $tempvar :=   for $m at $p in $root 
    let $diff := (xs:decimal($m/@EK) - xs:decimal($m/@AG))
    order by $diff descending
    return $m
  (: Numerierung loop ueber tempvar :)
  (: nr gibt Numerierung vor der Sortierung :)
  (: pos und nr2 gibt Numerierung nach der Sortierung :)
  for $m at $p in $tempvar 
    let $diff := (xs:decimal($m/@EK) - xs:decimal($m/@AG))
    return 
      <Problem>
      {attribute nr {index-of($root, $m)}}
      {attribute nr2 {index-of($tempvar, $m)}}
      {attribute pos {$p}}
      {attribute diff {$diff}}
      {for $a in $m/attribute::* return $a}
      {
      for $c in $m/child::* 
      return attribute {$c/local-name()} {$c/text()}
      } 
      </Problem>
}
</ERGEBNIS>

Das Endergebnis lautet dann:

<ERGEBNIS>
  <Problem nr="2" nr2="1" pos="1" 
           diff="-407.3699999999999" 
           EK="333.33" 
           AG="740.6999999999999" 
           Vorname="Rudi" 
           Nachname="Rhodos" 
           Stadt="Darmstadt"/>
  <Problem nr="3" nr2="2" pos="2" 
           diff="-487.13" 
           EK="321" 
           AG="808.13" 
           Vorname="Susi" 
           Nachname="Schlaflos" 
           Stadt="Kapstadt"/>
  <Problem nr="4" nr2="3" pos="3" 
           diff="-829.0699999999999" 
           EK="135" 
           AG="964.0699999999999" 
           Vorname="Liane" 
           Nachname="Leinenlos" 
           Stadt="Kapstadt"/>
  <Problem nr="1" nr2="4" pos="4" 
           diff="-3328.5800000000003" 
           EK="234.56" 
           AG="3563.1400000000003" 
           Vorname="Hugo" 
           Nachname="Holzflos" 
           Stadt="Neustadt"/>
</ERGEBNIS>

qrpic/XProc.jpg

wg / 6. September 2017




Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf (info10@wilfried-grupe.de).



Vielen Dank für Ihr Interesse an meiner Arbeit.


V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

Mobil: 0151. 750 360 61 * eMail: info10@wilfried-grupe.de