XSLT-Zählelemente mit einem bestimmten Wert

Ich muss die Anzahl der Elemente in einer XML-Datei zählen, die einen bestimmten Wert haben (um die Eindeutigkeit zu überprüfen). Die XML-Datei sieht wie folgt aus:

EDIT: Ich habe das ursprüngliche "vereinfachte" XML mit dem eigentlichen haarigen Durcheinander aktualisiert, das jemand entworfen hat. Leider wird dies alle vorherigen Antworten wirklich verwirrend und falsch machen, wenn nicht bearbeitet.

<root>
  <ac>
   <Properties>
     <Property Name="Alive">
      <Properties>
        <Property Name="ID">
         <Properties>
           <Property Name="Value">
            <long>11007</long>
           </Property>
         </Properties>
        </Property>
      </Properties>
     </Property>
     <Property Name="Dead">
      <Properties>
        <Property Name="ID">
         <Properties>
           <Property Name="Value">
            <long>11008</long>
           </Property>
         </Properties>
        </Property>
      </Properties>
     </Property>
     ...
     <Property Name="MostlyDeadAllDay">
      <Properties>
        <Property Name="ID">
         <Properties>
           <Property Name="Value">
            <long>99001</long>
           </Property>
         </Properties>
        </Property>
      </Properties>
     </Property>
   </Properties>
  </ac>
</root>

Ich versuche, eine Variable zu definieren, um zu sehen, wie viele der Eigenschaften auf der Alive/Dead-Ebene den Long-Wert (ID) haben, wie in einem Vorlagenparameter definiert. Etwas in dieser Richtung (obwohl ich vermute, dass dies falsch ist)...

<xsl:param name="parPropId"/>
<xsl:variable name="countProperties">
   <xsl:value-of select="count(/root/ac/
      Properties/Property/
      Properties/Property[@Name = 'ID']/
      Properites/Property[@Name = 'Value']/long = $parPropId)"/>
</xsl:variable>

Es können mehrere Eigenschaftselemente auf der Ebene "ID" definiert sein. Aber ich bin ziemlich sicher, dass ich mit nur einem Property-Element ("Value") unter "ID" und nur einem "langen" Element unter "Wert" rechnen kann.

[Haftungsausschluss] Wer auch immer die gesamte XML-Datei entworfen hat, mit der ich zusammenarbeite, wusste nicht, wie XML strukturiert werden sollte (z. B. rückwärts verwenden von Attributen im Vergleich zu Elementen). Ich fürchte, mein XSLT-Denken wurde vorübergehend :) als Ergebnis. [/Haftungsausschluss]

Antwort auf "XSLT-Zählelemente mit einem bestimmten Wert " 3 von antworten

<xsl:variable name="count" select="count(/Property/long = $parPropId)"/>

Ungetestet, aber ich denke, das sollte funktionieren. Ich gehe davon aus, dass die Eigenschaftsknoten direkte untergeordnete Elemente des Stammknotens sind und daher Ihren nachfolgenden Selektor für peformance

herausnehmen.

Ihr xpath ist nur ein wenig aus:

count(//Property/long[text()=$parPropId])

Bearbeiten: Cerebrus weist zu Recht darauf hin, dass der Code in Ihrem OP (mit dem impliziten Wert eines Knotens) für Ihre Zwecke absolut in Ordnung ist. Da Es sehr wahrscheinlich ist, dass Sie mit dem Knoten "Property" und nicht mit dem "langen" Knoten arbeiten möchten, ist es wahrscheinlich überlegen nach //Property[long=$parPropId] than the text() xpath, though you could make a case for the latter on readability grounds. als der Text() xpath zu fragen, obwohl Sie einen Fall für letztere aus Lesbarkeitsgründen machen könnten.

Was soll ich sagen, ich bin heute ein bisschen müde :)

Dieser XPath:

count(//Property[long = '11007'])

gibt den gleichen Wert zurück wie:

count(//Property/long[text() = '11007'])

... mit der Ausnahme, dass der erste Property nodes that match the criterion and the second counts Knoten zählt, die dem Kriterium entsprechen, und der zweite long child nodes that match the criterion. untergeordnete Knoten, die dem Kriterium entsprechen.

Nach Ihrem Kommentar und dem Lesen Ihrer Frage ein paar Mal, Ich glaube, dass Sie Einzigartigkeit auf der Grundlage einer Kombination von Kriterien zu finden wollen. Daher denke ich, dass Sie in Wirklichkeit tatsächlich mehrere Bedingungen überprüfen. Das Folgende würde auch funktionieren:

count(//Property[@Name = 'Alive'][long = '11007'])

, weil es dasselbe bedeutet wie:

count(//Property[@Name = 'Alive' and long = '11007'])

Natürlich würden Sie die Werte durch Parameter in Ihrer Vorlage ersetzen. Der obige Code veranschaulicht nur den Punkt.

EDIT (nach der Bearbeitung der Frage)


Sie hatten völlig Recht, dass die XML schrecklich war. In der Tat ist dies ein geradezu CodingHorror candidate! I had to keep recounting to keep track of the "Property" node I was on presently. I feel your pain! Kandidat! Ich musste immer wieder erzählen, um den "Property"-Knoten zu verfolgen, auf dem ich mich derzeit befand. Ich spüre deinen Schmerz!

Hier geht es los:

count(/root/ac/Properties/Property[Properties/Property/Properties/Property/long = $parPropId])

Beachten Sie, dass ich alle anderen Schecks entfernt habe (für ID und Wert). Sie scheinen nicht erforderlich zu sein, da Sie über die Hierarchie im XML-Code zum entsprechenden Knoten gelangen können. Außerdem haben Sie bereits erwähnt, dass die Prüfung auf Eindeutigkeit nur auf dem Inhalt des long element.-Elements basiert.