2000–2011: 12 Jahre FrameMaker-Spezialist

Sehr geehrte, liebe Kunden,

seit 1993 bin ich im Bereich der Technischen Dokumentation als Spezialist für Dokumentationstechnologie tätig. In den letzten zwölf Jahren in erster Linie als FrameMaker-Experte, seit ca. 2005 kamen XML-basierte Prozesse mit und ohne FrameMaker hinzu.

Ab Januar 2012 werde ich die Firma DOCUFY GmbH in Bamberg Weiterlesen

Veröffentlicht unter Sonstiges | Ein Kommentar

XML für Helden

Veröffentlicht unter XML/XSL | Kommentare deaktiviert für XML für Helden

Tekom 2013, Do 7.11.2013

Am zweiten Tag der diesjährigen tekom-Jahrestagung kam ich nicht in so viele Vorträge – meinen eigenen habe ich natürlich besucht! – aber ein paar Notizen sind es dennoch geworden. Den Freitag habe ich in diesem Jahr erstmalig nicht mehr besucht. Weiterlesen

Veröffentlicht unter tekom/tcworld | Kommentare deaktiviert für Tekom 2013, Do 7.11.2013

Tekom 2013, Mi 6.11.2013

Am ersten Tag der diesjährigen tekom-Jahrestagung konnte ich einige Vorträge besuchen. Hier meine kurzen Notizen. Weiterlesen

Veröffentlicht unter tekom/tcworld | Kommentare deaktiviert für Tekom 2013, Mi 6.11.2013

XML Prague 2013

http://xmlprague.cz/

Guten Morgen aus Prag, gerade beginnt die 8. Konferenz XML Prague, aufgrund des Erfolgs jetzt zum zweiten Mal in großen Hörsaal der wirtschaftswissenschaftlichen Fakultät. Als Single Track Conference ist es (für mich) äußerst entspannend, mich nicht zwischen verschiedenen, parallelen Vorträgen entscheiden zu müssen. Weiterlesen

Veröffentlicht unter XML/XSL | Kommentare deaktiviert für XML Prague 2013

Wähle drei Töpfe

Intelligenius

Jeder Topf hat vier Eigenschaften:

  • verschiedene Deckel: kein Deckel, flacher Griff, hoher Griff
  • verschiedene Farben: hell, gestreift, dunkel
  • verschiedene Zeichen: Ring, Kreuz, Doppelkreuz
  • verschiedene Zeichenanzahl: 1, 2 oder 3

Es sollen genau drei Töpfe so ausgewählt werden, dass für jede der vier Eigenschaften alle Töpfe entweder den gleichen Wert oder alle unterschiedliche Werte haben.

XML-Notation

Die Eigenschaften sind Attribute (zur Vereinfachung nenne ich diese a, b, c und d) und jedes Attribut muss einen von drei möglichen Werten annehmen (1, 2, 3).

<pots>
    <pot a="1" b="1" c="3" d="2"></pot>
    <pot a="1" b="1" c="3" d="3"></pot>
    <pot a="3" b="2" c="1" d="2"></pot>
    <pot a="1" b="3" c="2" d="1"></pot>
    <pot a="1" b="1" c="1" d="1"></pot>
    <pot a="2" b="2" c="1" d="2"></pot>
    <pot a="3" b="2" c="2" d="1"></pot>
    <pot a="3" b="2" c="1" d="1"></pot>
    <pot a="3" b="1" c="3" d="2"></pot>
    <pot a="3" b="1" c="1" d="1"></pot>
    <pot a="2" b="1" c="3" d="2"></pot>
    <pot a="3" b="2" c="3" d="3"></pot>
</pots>

Lässt sich die Lösung mit einem XPath-Ausdruck angeben? Nein, wohl nicht, und ich bin auch nur auf eine brute force-Lösung gekommen, die mir wenig elegant erscheint:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:my="my" 
  exclude-result-prefixes="#all">
  <xsl:output indent="yes" />

  <xsl:template match="pots">
    <xsl:variable name="a" as="node()*" select="my:triples(*, 'a')" />
    <xsl:variable name="b" as="node()*" select="my:triples(*, 'b')" />
    <xsl:variable name="c" as="node()*" select="my:triples(*, 'c')" />
    <xsl:variable name="d" as="node()*" select="my:triples(*, 'd')" />
    <result>
      <!-- only triples which are present for all attributes are returned -->
      <xsl:for-each select="$a[. = $b][. = $c][. = $d]">
        <xsl:sequence select="." />
      </xsl:for-each>
    </result>
  </xsl:template>

  <!-- this function returns all valid triples for a single attribute -->
  <xsl:function name="my:triples" as="node()*">
    <xsl:param name="nodes" as="node()+" />
    <xsl:param name="attr" as="xs:string" />

    <!-- look for common values -->
    <xsl:for-each select="$nodes">
      <xsl:variable name="t1" select="." />
      <xsl:for-each select="$t1/following-sibling::*[@*[name() eq $attr] eq $t1/@*[name() eq $attr]]">
        <xsl:variable name="t2" select="." />
        <xsl:for-each select="$t2/following-sibling::*[@*[name() eq $attr] eq $t1/@*[name() eq $attr]]">
          <triple>
            <xsl:value-of select="(my:pos($nodes, $t1), my:pos($nodes, $t2), my:pos($nodes, .))" />
          </triple>
        </xsl:for-each>
      </xsl:for-each>
    </xsl:for-each>

    <!-- look for distinct values -->
    <xsl:for-each select="$nodes">
      <xsl:variable name="t1" select="." />
      <xsl:for-each select="$t1/following-sibling::*[@*[name() eq $attr] ne $t1/@*[name() eq $attr]]">
        <xsl:variable name="t2" select="." />
        <xsl:for-each select="
              $t2/following-sibling::*[@*[name() eq $attr] ne $t1/@*[name() eq $attr] 
              and 
              @*[name() eq $attr] ne $t2/@*[name() eq $attr]]">
          <triple>
            <xsl:value-of select="(my:pos($nodes, $t1), my:pos($nodes, $t2), my:pos($nodes, .))" />
          </triple>
        </xsl:for-each>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:function>

  <xsl:function name="my:pos" as="xs:string">
    <xsl:param name="nodes" as="node()+" />
    <xsl:param name="node" as="node()" />
    <xsl:value-of select="count($nodes[$node >> .]) + 1" />
  </xsl:function>

</xsl:transform>

Wer kann eine elegantere Lösung anbieten?

Veröffentlicht unter XML/XSL | Kommentare deaktiviert für Wähle drei Töpfe