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


Gruppierung optionaler Werte

Wenn wir das XML Dokument mit dem folgenden XSL transformieren,

 <ergebnis>
  <xsl:for-each select="Orte/Ort">
   <PLZ info="{PLZ}">
    <xsl:value-of select="name" />
   </PLZ>
  </xsl:for-each>
 </ergebnis>

... dann erhalten wir (logischerweise) ein Ergebnis, das zwar für jeden Ort ein "PLZ"-Element ausgibt, das aber nur dort mit Inhalt gefüllt ist, wo das XML Input Dokument auch einen Childnode "PLZ" aufweist.

   <ergebnis>
      <PLZ info="">Neustadt</PLZ>
      <PLZ info="61000">Darmstadt</PLZ>
      <PLZ info="">Kapstadt</PLZ>
   </ergebnis>

Arbeiten wir dagegen mit "xsl:for-each-group" und gruppieren wir über "PLZ",

 <ergebnis>
  <xsl:for-each-group 
       select="Orte/Ort" 
       group-by="PLZ">
   <PLZ info="{current-grouping-key()}">
    <xsl:for-each select="current-group()">
     <Ort>
      <xsl:value-of select="name" />
     </Ort>
    </xsl:for-each>
   </PLZ>
  </xsl:for-each-group>
 </ergebnis>

so werden jene XML Elemente, die das optionale Element "PLZ" nicht aufweisen, ausgeblendet. Das Ergebnis lautet:

   <ergebnis>
      <PLZ info="61000">
         <Ort>Darmstadt</Ort>
      </PLZ>
   </ergebnis>

Das Ergebnis wäre hier faktisch dasselbe, als hätten wir uns von vornherein auf die Nodelist "Orte/Ort/PLZ" konzentriert, die per Definition sämtliche "Ort"-Nodes ohne "PLZ"-Child ignoriert:

 <ergebnis>
  <xsl:for-each select="Orte/Ort/PLZ">
   <PLZ info="{.}">
    <Ort>
     <xsl:value-of select="../name" />
    </Ort>
   </PLZ>
  </xsl:for-each>
 </ergebnis>

... oder auch mit Gruppierung ...

 <ergebnis>
  <xsl:for-each-group 
       select="Orte/Ort/PLZ" 
       group-by=".">
   <PLZ info="{.}">
    <Ort>
     <xsl:value-of select="../name" />
    </Ort>
   </PLZ>
  </xsl:for-each-group>
 </ergebnis>

Um auch ausgeblendete "Ort"-Elemente in unserem Listing zu berücksichtigen, können wir für einen modifizierten XML Input sorgen, der in jedem Fall über ein "PLZ"-Element verfügt. Dies mag geschehen durch eine separate Variable, die ich hier "vort" genannt habe.

 <xsl:variable name="vort">
  <xsl:for-each select="Orte/Ort">
   <Ort>
    <id>
     <xsl:value-of select="id" />
    </id>
    <name>
     <xsl:value-of select="name" />
    </name>
    <PLZ>
     <xsl:value-of select="PLZ" />
    </PLZ>
   </Ort>
  </xsl:for-each>
 </xsl:variable>
 <ergebnis>
  <xsl:for-each-group 
       select="$vort/Ort" 
       group-by="PLZ">
   <PLZ info="{current-grouping-key()}">
    <xsl:for-each select="current-group()"> 
     <Ort><xsl:value-of select="name" /></Ort>
    </xsl:for-each>
   </PLZ>
  </xsl:for-each-group>
 </ergebnis>

Die temporäre Variable "vort" hat dann einen Aufbau, in dem jedes "Ort"-Element zuverlässig einen Childnode "PLZ" hat, auch wenn dessen Inhalt leer ist:

   <Ort>
      <id>1</id>
      <name>Neustadt</name>
      <PLZ/>
   </Ort>
   <Ort>
      <id>2</id>
      <name>Darmstadt</name>
      <PLZ>61000</PLZ>
   </Ort>
   <Ort>
      <id>3</id>
      <name>Kapstadt</name>
      <PLZ/>
   </Ort>

Wenn wir diese temporäre Variable "vort" als Input nehmen, können wir mit der Anweisung <xsl:for-each-group select="$vort/Ort" group-by="PLZ"> dafür sorgen, daß auch die vorher ausgeblendeten Elemente im Fokus bleiben.

   <ergebnis>
      <PLZ info="">
         <Ort>Neustadt</Ort>
         <Ort>Kapstadt</Ort>
      </PLZ>
      <PLZ info="61000">
         <Ort>Darmstadt</Ort>
      </PLZ>
   </ergebnis>

qrpic/optionaleElemente2.jpg

wg / 15. 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