Gern stehe ich zur fachlichen Unterstützung in XML-Technologien, C#.NET, VisualBasic.NET und Java zur Verfügung. Sprechen Sie mich einfach an: Mail oder ☎ 0151 . 750 360 61


XPath 3.0, XPath 2.0, XPath 1.0 / XPath-Funktionen / XPath: Sequenz-Funktionen / XPath Sequenzen: concat, union, except, intersect

XPath Sequenzen: concat, union, except, intersect

XPath Sequenzen: concat, union, except, intersect

➪ Ab XSLT/XPath 2.0 sind Sequenzen äußerst leistungsfähig, nicht zuletzt durch die Möglichkeiten der Mengenoperationen: concat, union, except, intersect. Zusätzliche Hilfe bietet die Arbeit mit distinct-values.

Auf dieser Seite:

Die Möglichkeiten der Mengenoperationen möchte ich mithilfe zweier Beispiele darstellen.

Das erste Beispiel besteht aus zwei Variablen, die beide Sequenzen einzelner Nodes umfassen. Die erste Variable "v1" umfasst die beiden Ort-Nodes 1 und 2 mit all deren Childnodes. Mit dem Komma-Operator wurden die beiden Ort-Nodes verkettet. Die Variable "v2" umfasst dagegen die beiden Ort-Nodes 2 und 3. Es gibt also eine Überschneidung bei Ort[2].


<xsl:variable name="v1" select="//Ort[1], //Ort[2]"/>
<xsl:variable name="v2" select="//Ort[2], //Ort[3]"/>

Das zweite Beispiel besteht aus zwei xs:integer-Zahlenmengen, die keine Nodes darstellen:


(1 to 7, 9)
(2, 5 to 10)

Sequenzen verketten

Mit dem Komma "," können Sie Sequenzen des ersten Beispiels verketten.


<CONCAT>
  <xsl:for-each select="$v1, $v2">
    <ortname><xsl:value-of select="name"/></ortname>
  </xsl:for-each>
</CONCAT>

Resultat:


<ortname>Neustadt</ortname>
<ortname>Darmstadt</ortname>
<ortname>Darmstadt</ortname>
<ortname>Kapstadt</ortname>

Im zweiten Beispiel, den Sequenzen (1 to 7, 9) und (2, 5 to 10), funktioniert die Verkettung ebenfalls recht einfach:


<concat>
    <xsl:value-of 
         select="(1 to 7, 9), (2, 5 to 10)" 
         separator=";"/>
</concat>

Das Ergebnis ist nachvollziehbar:


<concat>1;2;3;4;5;6;7;9;2;5;6;7;8;9;10</concat>

Sequenzen vereinigen mit union

Mit union oder auch "|" können Sie Sequenzen vereinigen. Dabei werden Überschneidungen wie bei Ort[2] vermieden.


<UNION>
  <xsl:for-each select="$v1 | $v2">
 <ortname><xsl:value-of select="name"/></ortname>
  </xsl:for-each>
</UNION>

Alternative: Arbeiten mit union.


<UNION>
  <xsl:for-each select="$v1 union $v2">
    <ortname><xsl:value-of select="name"/></ortname>
  </xsl:for-each>
</UNION>

Resultat:


<ortname>Neustadt</ortname>
<ortname>Darmstadt</ortname>
<ortname>Kapstadt</ortname>

Im zweiten Beispiel, den Sequenzen (1 to 7, 9) und (2, 5 to 10), können Sie in XSL 3.0 eine mithilfe von schreiben (vgl. http://www.xqueryfunctions.com/xq/functx_value-union.html bzw. http://www.xsltfunctions.com/xsl/functx_value-union.html: hier wurde die Funktion mit functx:value-union für xs:anyAtomicType allgemeiner formuliert):


<xsl:stylesheet version="3.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:wg="http://www.wilfried-grupe.de"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
...
<union>
    <xsl:variable name="f_union" 
        select="function($menge1 as xs:integer*, $menge2 as xs:integer*) 
        as xs:integer*
        {distinct-values(($menge1, $menge2))}"/>               
    <xsl:value-of select="$f_union((1 to 7, 9) , (2, 5 to 10))" separator=";"/>
</union>
...

... alternativ:


<union>
    <xsl:value-of 
         select="distinct-values(((1 to 7, 9), (2, 5 to 10)))" 
         separator=";"/>
</union>

Das Ergebnis ist jedes Mal:


<union>1;2;3;4;5;6;7;9;8;10</union>

Sequenzen ausschließen mit except

Mit except können Sie Teilsequenzen ausschließen, etwa nach dem Konzept Sequenz1 ohne Sequenz2. Überschneidungen beider Sequenzen werden damit ausgeschlossen.


<EXCEPT>
  <xsl:for-each select="$v1 except $v2">
    <ortname><xsl:value-of select="name"/></ortname>
  </xsl:for-each>
</EXCEPT>

Resultat:


<ortname>Neustadt</ortname>

Im zweiten Beispiel, den Sequenzen (1 to 7, 9) und (2, 5 to 10), können Sie in XSL 3.0 Zahlenmengen mithilfe von und ausschließen (vgl. http://www.xsltfunctions.com/xsl/functx_value-except.html bzw. http://www.xqueryfunctions.com/xq/functx_value-except.html: hier wurde die Funktion mit functx:value-except für xs:anyAtomicType allgemeiner formuliert):


<xsl:stylesheet version="3.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:wg="http://www.wilfried-grupe.de"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
...
<except>
    <xsl:variable name="f_except" 
        select="function($menge1 as xs:integer*, $menge2 as xs:integer*) 
        as xs:integer*
        {distinct-values($menge1[not(.=$menge2)])}"/>    
    <xsl:value-of select="$f_except((1 to 7, 9) , (2, 5 to 10))" separator=";"/>
</except>
...

... oder alternativ:


<except>     
    <xsl:value-of 
         select="distinct-values( (1 to 7, 9)[not(. = (2, 5 to 10))])" 
         separator=";"/>
</except>

Das Ergebnis ist jedes Mal:


<except>1;3;4</except>

Schnittmengen von Sequenzen bilden mit intersect

Mit intersect können Sie Schnittmengen von Sequenzen ermitteln.


<xsl:for-each select="$v1 intersect $v2">
  <ortname><xsl:value-of select="name"/></ortname>
</xsl:for-each>

Das Resultat ist eine Sequenz, in der nur Items vorkommen, die in den beiden ursprünglichen Sequenzen gemeinsam vorkommen.


<ortname>Darmstadt</ortname>

Im zweiten Beispiel, den Sequenzen (1 to 7, 9) und (2, 5 to 10), können Sie in XSL 3.0 können Sie Schnittmengen von Zahlenmengen bilden, indem Sie eine entsprechende mithilfe von schreiben (vgl. http://www.xsltfunctions.com/xsl/functx_value-intersect.html bzw. http://www.xqueryfunctions.com/xq/functx_value-intersect.html: hier wurde die Funktion mit functx:value-intersect für xs:anyAtomicType allgemeiner formuliert):


<xsl:stylesheet version="3.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:wg="http://www.wilfried-grupe.de"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
...
<intersect>
    <xsl:variable name="f_intersect" 
        select="function($menge1 as xs:integer*, $menge2 as xs:integer*) 
        as xs:integer*
        {distinct-values($menge1[.=$menge2])}"/>    
    <xsl:value-of 
         select="$f_intersect((1 to 7, 9) , (2, 5 to 10))" 
         separator=";"/>
</intersect>
...

... oder auch:


<intersect>     
    <xsl:value-of 
         select="distinct-values((1 to 7, 9)[. = (2, 5 to 10)])" 
         separator=";"/>
</intersect>

Das Ergebnis ist jedes Mal:


<intersect>2;5;6;7;9</intersect>

wg / 1. Mai 2019



Fragen? Anmerkungen? Tipps?

Bitte nehmen Sie Kontakt zu mir auf.






Vielen Dank für Ihr Interesse an meiner Arbeit.


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

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

www.wilfried-grupe.de/concatunionexceptintersect.html