2011-01-10 20 views
1

nicht wissen, wie es klar zu erklären, so dass ich nur ein Beispiel geben: XML-Datei:wenn mit mehreren Elementen

<root> 
    <one> 
    <a a="x"/> 
    <a a="y"/> 
    </one> 
    <two> 
    <a a="x"/> 
    <a a="y"/> 
    </two> 
</root> 

und hier ist ein xsl:

<xsl:template match="/root"> 
     <xsl:variable name="self" select="."/> 

     <xsl:if test="one/a/@a = $self/two/*/a/@a"> 
      <xsl:text>it works</xsl:text> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

I nur wollen, die, wenn zu arbeiten ...

// bearbeiten

Eine Erklärung:

<requirements> 
    <bar/><restaurant/> 
</requirements> 
<offer> 
    <bar/></beach><restaurant/><nightclub/> 
<offer> 

so will ich das ‚wenn‘ zu prüfen, ob alle (in diesem Fall) Elemente von ‚Anforderungen‘ erfüllt werden, die durch die Elemente von ‚Angebot‘

+0

Was soll die 'if' Bedingung genau testen? –

+0

Soll die if-Anweisung bedeuten: "Finde irgendeinen unter" eins ", wo sein @a mit einem der a's unter" zwei "mit dem gleichen @a-Parameter übereinstimmt?" Es ist unklar, was deine if-Aussage bedeuten soll. – Jacob

+0

@Greg, ich denke, er versucht zu überprüfen, ob es eine Übereinstimmung in 'zwei' für das Element in' one/a' gibt. – CaffGeek

Antwort

0

Vielleicht ist dies?

<xsl:template match="/root"> 
    <xsl:variable name="self" select="."/> 
    <xsl:variable name="aKey" select="one/a/@a"/> 

    <xsl:if test="$self/two/*/a[@a=$aKey]"> 
     <xsl:text>it works</xsl:text> 
    </xsl:if> 
</xsl:template> 
0

EDIT

XSLT 1.0 Lösung:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="validTest"> 
    <xsl:for-each select="/*/requirements/*"> 
     <xsl:value-of select="concat(name(),'+')"/> 
    </xsl:for-each> 
</xsl:variable> 

<xsl:template match="offer"> 
    <xsl:if test="count(/*/requirements/*) = count(*[ 
            contains($validTest, 
             concat(name(),'+') 
             ) 
            ])"> 
     <xsl:value-of select="concat('#', @id, ' is a valid offer!&#xa;')"/> 
    </xsl:if> 
</xsl:template> 
</xsl:stylesheet> 

auf die XML-Probe angewendet:

<root> 
    <requirements> 
    <bar/><restaurant/> 
    </requirements> 
    <offer id="1"> 
    <bar/><beach/><restaurant/><nightclub/> 
    </offer> 
    <offer id="2"> 
    <bar/><beach/><nightclub/> 
    </offer> 
    <offer id="2"> 
    <beach/><nightclub/><restaurant/> 
    </offer> 
    <offer id="4"> 
    <bar/><beach/><restaurant/><nightclub/> 
    </offer> 
</root> 

produziert dieses Ergebnis:

#1 is a valid offer! 
#4 is a valid offer! 
+0

es funktioniert nicht richtig - wenn Sie 'a ändern 'Attribut in einem von' x 'zu etwas anderem, es druckt immer noch' es funktioniert ', aber es sollte nicht – tom

+0

so müssen Sie Attributwerte verglichen werden, unter Berücksichtigung der Attribute Position? z.B. wenn zuerst _ein/a/@ a_ zuerst gepasst wird _two/a/@ a_? – Flack

+0

Position ist irrelevant, schaue ein anderes Beispiel am Ende meiner Frage, habe ich das – tom

0

Sie suchen Vielleicht

test = "every $ x in $ self/one/xxx erfüllt einige $ y in $ self/two/yyy erfüllt $ x = $ y"

+0

@Micheal Kay: +1 besser XPath 2.0 Ausdruck und vor ... –

1

dieses XSLT Stylesheet 1.0:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="kElementByName" match="requirements/*" use="name()"/> 
    <xsl:template match="offer[count(*[key('kElementByName',name())]) 
           = count(../requirements/*)]"> 
     <xsl:text>Success!</xsl:text> 
    </xsl:template> 
</xsl:stylesheet> 

Mit diesem Eingang (well) gebildet:

<root> 
    <requirements> 
     <bar/> 
     <restaurant/> 
    </requirements> 
    <offer> 
     <bar/> 
     <beach/> 
     <restaurant/> 
     <nightclub/> 
    </offer> 
</root> 

Output:

Success! 

Hinweis: Die Verwendung von xsl:key da Funktionen impliziten Knotensatz Guss nur skalare nimmt den ersten Knoten.

XPath 2.0 expression:

every $name in /root/requirements/*/name() 
satisfies $name = /root/offer/*/name() 
+0

+1. Verdammt, wie habe ich Schlüssel für diesen hier vergessen. – Flack

1

verwenden XPath 2.0 Ausdruck:

not($requirements[not(name()=$offer/name())]) 

wo:

$requirements ist /*/requirements/*

und

$offer ist /*/offer/*

und diese gegen das XML-Dokument ausgewertet unter (im Wesentlichen der vorgesehenen nicht-XML wohlgeformte XML-Dokument wohlgeformten gemacht):

<t> 
    <requirements> 
     <bar/> 
     <restaurant/> 
    </requirements> 
    <offer> 
     <baz/> 
     <beach/> 
     <restaurant/> 
     <nightclub/> 
    </offer> 
</t> 

Die gleiche Technik für Ihr erstes Problem:

not(/*/one/a[not(@a = /*/two/a/@a)]) 

Beachten Sie, dass es sich bei der oben genannten Lösung um eine Ein-Liter-XPath 1.0-Lösung handelt. :)

+0

+1 für den XPath-One-Liner. Besser spät als nie :) – Flack

Verwandte Themen