2017-11-28 2 views
2

Ich habe ein Szenario, in dem ich die XML-Tag-Werte unabhängig von seinem Tag-Namen zählen muss. Unten ist mein xml,Zähle xml-Tag-Werte unabhängig vom Tag-Namen mit XSLT

<?xml version="1.0" encoding="UTF-8"?> 
<output> 
    <result> 
     <value> 
     <color1>G</color1> 
     <color2>Y</color2> 
     </value> 
     <value> 
     <color1>Y</color1> 
     <color2>R</color2> 
     </value> 
    </result> 
    <result> 
     <value> 
     <color1>G</color1> 
     <color2>R</color2> 
     </value> 
     <value> 
     <color1>Y</color1> 
     <color2>R</color2> 
     </value> 
    </result> 
</output> 
  1. Hier muss ich die Anzahl der Vorkommen von G, Y, R aus der XPath // Ausgabe zählen/Ergebnis sollte
  2. Der Wert innerhalb // Ausgabe/Ergebnis bleiben und können es in der Ausgabe hinzufügen. Unten ist die xslt, die ich verwendet, aber es gibt immer zählen als 0.

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
         xmlns:xs="http://www.w3.org/2001/XMLSchema" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"> 
    
        <xsl:template match="/"> 
         <output> 
          <xsl:for-each select="//output/result"> 
          <result> 
        <green><xsl:value-of select="count(/value[./color[*]='G'])" /></green> 
        <red><xsl:value-of select="count(/value[./color[*]='R'])" /></red> 
        <yellow><xsl:value-of select="count(/value[./color[*]='Y'])" /</yellow> 
           <xsl:value-of select="." /> 
          </result> 
         </xsl:for-each> 
         </output> 
        </xsl:template> 
    </xsl:stylesheet> 
    

Die gewünschte Ausgabe als unten.

<?xml version="1.0" encoding="UTF-8"?> 
<output> 
    <result> 
    <GreenCount>1</GreenCount> 
<RedCount>1</RedCount> 
<YellowCount>2</YellowCount> 
     <value> 
     <color1>G</color1> 
     <color2>Y</color2> 
     </value> 
     <value> 
     <color1>Y</color1> 
     <color2>R</color2> 
     </value> 

    </result> 
    <result> 
    <GreenCount>1</GreenCount> 
<RedCount>2</RedCount> 
<YellowCount>1</YellowCount> 

     <value> 
     <color1>G</color1> 
     <color2>R</color2> 
     </value> 
     <value> 
     <color1>Y</color1> 
     <color2>R</color2> 
     </value> 
    </result> 
</output> 

Antwort

1

Sie versuchen, XSL zu programmieren, als ob es eine imperative Sprache wäre. Es ist nicht so, dass die Eingabe-XML den Prozess antreibt und die XSL "reagiert", wenn Eingabe-Tags mit Vorlagen abgeglichen werden.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="result"> 
     <xsl:copy> 
      <GreenCount><xsl:value-of select="count(value/*[text() = 'G'])"/> </GreenCount> 
      <RedCount><xsl:value-of select="count(value/*[text() = 'R'])"/></RedCount> 
      <YellowCount><xsl:value-of select="count(value/*[text() = 'Y'])"/></YellowCount> 
      <xsl:apply-templates/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

Die erste Vorlage ist ein, dass Kopien Eingang zum Ausgang unverändert „Identität verwandeln“, da Sie nur Tags mit dem Eingang hinzufügen.

Dann wird für jeden result (nicht XSL for-each, sondern nur die natürliche Reihenfolge der Verarbeitung lassen füttern Sie die result Elemente):

  1. Kopieren Sie die result Tag
  2. Generieren Sie die drei Zusammenfassung Tags durch Zählen Kinder von value Tags mit dem gewünschten Text
  3. Für den Rest des Inhalts des Tags result rekursiv erneut den Prozess mit der Identity-Transformation, um sie auf die Ausgabe zu kopieren.

Dies erzeugt die folgende Ausgabe:

<?xml version="1.0" encoding="UTF-8"?> 
<output> 
    <result> 
     <GreenCount>1</GreenCount> 
     <RedCount>1</RedCount> 
     <YellowCount>2</YellowCount> 
     <value> 
      <color1>G</color1> 
      <color2>Y</color2> 
     </value> 
     <value> 
      <color1>Y</color1> 
      <color2>R</color2> 
     </value> 
    </result> 
    <result> 
     <GreenCount>1</GreenCount> 
     <RedCount>2</RedCount> 
     <YellowCount>1</YellowCount> 
     <value> 
      <color1>G</color1> 
      <color2>R</color2> 
     </value> 
     <value> 
      <color1>Y</color1> 
      <color2>R</color2> 
     </value> 
    </result> 
</output> 
+0

Vielen Dank Jim. –

Verwandte Themen