2017-12-20 5 views
-1

Meine Zählung ist in Ordnung, aber wenn ich weiter nach CODE = 'A' oder 'B' filtere, bekomme ich auch 'C' für NODE GUID = "2".XSLT-Filter funktioniert nicht

Es sieht ziemlich geradlinig aus, aber ich bin mir nicht sicher, was ich falsch mache.

Jede Hilfe würde sehr geschätzt werden. Danke im Voraus.

Siehe XSLT für den XPATH-Ausdruck.

Das ist mein XML:

<?xml version="1.0" encoding="UTF-8"?> 
<NODEs> 
    <NODE GUID="2"> 
     <Name>Michael</Name> 
     <Activities/> 
    <NODEs> 
     <NODE GUID="1"> 
      <Name>Larry</Name> 
      <ParentNODE>2</ParentNODE> 
      <Activities> 
       <Activity GUID="A1"> 
        <ActivityCodes> 
         <ActivityCode> 
          <CodeTypeName>CODE</CodeTypeName> 
          <CodeValue>A</CodeValue> 
         </ActivityCode> 
        </ActivityCodes> 
       </Activity> 
      </Activities> 
     </NODE> 
     <NODE GUID="2"> 
      <Name>Joe</Name> 
      <ParentNODE>2</ParentNODE> 
      <Activities> 
       <Activity GUID="A2"> 
       <NODECode>2</NODECode> 
       <ActivityCodes> 
        <ActivityCode> 
         <CodeTypeName>CODE</CodeTypeName> 
         <CodeValue>A</CodeValue> 
        </ActivityCode> 
       </ActivityCodes> 
      </Activity> 
      <Activity GUID="A3"> 
       <NODECode>2</NODECode> 
       <ActivityCodes> 
        <ActivityCode> 
         <CodeTypeName>CODE</CodeTypeName> 
         <CodeValue>C</CodeValue> 
        </ActivityCode> 
       </ActivityCodes> 
      </Activity> 
      <Activity GUID="A4"> 
      <NODECode>2</NODECode> 
      <ActivityCodes> 
       <ActivityCode> 
        <CodeTypeName>CODE</CodeTypeName> 
        <CodeValue>B</CodeValue> 
       </ActivityCode> 
      </ActivityCodes> 
     </Activity> 
     </Activities> 
    </NODE> 
    </NODEs> 
    </NODE> 
</NODEs> 

Dies ist relevant XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="2.0" 
    xmlns:saxon="http://saxon.sf.net/" 
    xmlns:PS="http://localhost" 
    exclude-result-prefixes="saxon PS"> 

    <xsl:apply-templates select=".//Activity" mode="I_NODE">     
    </xsl:apply-templates> 

    <xsl:template match="Activity" mode="I_NODE"> 
    <xsl:variable name="Code" select="ActivityCodes/ActivityCode[CodeTypeName = 'CODE']/CodeValue"/> <!-- 'A'/'B' --> 

    <xsl:if test="$Code = 'A' or $Code = 'B'"> 
     <NODE> 
     <xsl:variable name="Count" select="count(preceding-sibling::*[$Code = 'A' or $Code = 'B']) +1"/> 
     <xsl:value-of select="$Count"/>  
     </NODE> 
    </xsl:if> 
    </xsl:template> 

</xsl:stylesheet> 

Stromausgang:

<NODE>1</NODE> 
<NODE>1</NODE> 
<NODE>3</NODE> 

Erwartete Ausgabe:

<NODE>1</NODE> 
<NODE>1</NODE> 
<NODE>2</NODE> 
+0

In welchem ​​Kontext verwenden Sie diesen XPath? Es ist ein wenig schwierig, nur mit dem XPath zu debuggen. Außerdem ist dieser XPath ungültig. https: // Stapelüberlauf.com/help/mcve –

+0

Es ist von xslt: Jkoul

+0

Der betreffende XPath-Ausdruck hat eine etwas andere Form in der von Ihnen bearbeiteten XSLT als der eigenständige XPath-Ausdruck, über den Sie ursprünglich verfügen fragte. Der neue Ausdruck verwendet außerdem eine Variable $ SAPInternalCode, die nirgendwo definiert ist. Vielleicht meinst du dort "Code", aber wenn, dann denke ich nicht, dass der Ausdruck das bedeutet, was du denkst, dass es bedeutet. Insbesondere ist es dann nicht analog zu dem Ausdruck, den Sie ursprünglich gepostet haben. –

Antwort

0

Ihre XPath scheint fehlerhaft zu sein:

count(preceding-sibling::*[ActivityCodes/ActivityCode[CodeTypeName = 'CODE']/CodeValue = 'A'] or [ActivityCodes/ActivityCode[CodeTypeName = 'CODE']/CodeValue = 'B']) +1 

es sieht aus wie Sie bedeuten die or Zustand in einem Prädikat sein statt zwischen zwei Prädikate:

count(preceding-sibling::*[ActivityCodes/ActivityCode[CodeTypeName = 'CODE']/CodeValue = 'A' or ActivityCodes/ActivityCode[CodeTypeName = 'CODE']/CodeValue = 'B']) +1 

, dass alle vorherigen Geschwister des Kontextknotens, der einen Abkömmling haben ActivityCodes/ActivityCode/CodeValue zählen wird, wo der ActivityCode ein 'B'CodeTypeName Kind mit dem Wert und der 'CODE'CodeValue hat Wert hat.

count(preceding-sibling::*[ActivityCodes/ActivityCode[CodeTypeName = 'CODE'][CodeValue = 'A' or CodeValue = 'B']) +1 

Persönlich finde ich die kompaktere Version klarer, auch: Sie sollten die gleiche Sache ein wenig kompakter aber zum Ausdruck bringen können.

+0

Das ist seltsam. Ich habe beide Versionen ausprobiert und in beiden Fällen habe ich für Node 2 eine Zahl von 3, also wird 'C' immer noch gezählt. Ich stelle mir vor, dass es für die Kompaktversion ein ']' kurz vor dem ')' geben sollte. – Jkoul

+0

Ich habe auch versucht, den Pfad in eine Variable zu setzen, aber immer noch Zählung von 3 für den NODE mit dem Namen 'Joe': Jkoul

+0

@jkoul, Beachten Sie, dass Ihr Ausdruck am Ende eine "+ 1" hat, die von mir übernommen wird. –

0

Wenn Sie wollen einfach Menge aller ActivityCode Blöcke zählen, wo CodeTypeName = 'CODE' und CodeValue = 'A' und +1 dann wie unten verwenden zählen:

count(//ActivityCode[CodeTypeName = 'CODE' and CodeValue = 'A']) + 1 

Ergebnis:

3 

Aber wenn Sie wollen Menge aller zählen ActivityCode Blöcke, wo CodeTypeName = 'CODE'CodeValue = 'A' und in Block, in die NODEGUID = '2' und +1 (wie oben), wie unten verwenden:

count(/NODEs/NODE[@GUID = '2']/NODEs/NODE[@GUID = '2']//ActivityCode[CodeTypeName = 'CODE' and CodeValue = 'A']) + 1 

Ergebnis:

2 
+0

Danke @ O.F. aber es kann mehrere verschachtelte Ebenen von NODEs/NODE geben. Meine Beispiel-XML war ein sehr kleiner Datenschnipsel. – Jkoul