2016-04-08 17 views
1
nicht

Ich habe eine XML-DateiFiltering xml mit Xslt arbeiten

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="main.xsl"?> 
<document> 
    <parents> 
     <parent> 
      <name>Jordan</name> 
      <age>25</age> 
      <childs> 
       <child eyes="black"> 
        <name>Ema</name> 
       </child> 
       <child eyes="blue"> 
        <name>Kaloyan</name> 
       </child>     
      </childs> 
     </parent> 
    </parents> 
</document> 

, die ich mit xsl Datei main.xsl filtern möchten:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" /> 
    <xsl:include href="child.xsl" /> 
    <xsl:template match="/"> 
     <html> 
      <head> 
       <title>Head first</title> 
      </head> 
      <body> 
       <table border="1"> 
        <xsl:for-each select="document/parents/parent"> 
         <tr> 
          <td> 
           <xsl:text disable-output-escaping="yes">Name</xsl:text> 
          </td> 
          <td> 
           <xsl:value-of select="name"></xsl:value-of> 
          </td> 
         </tr> 
         <tr> 
          <td> 
           <xsl:text disable-output-escaping="yes">Age</xsl:text> 
          </td> 
          <td> 
           <xsl:value-of select="age"></xsl:value-of> 
          </td> 
         </tr> 
         <xsl:for-each select="childs/child"> 
          <xsl:variable name="obj" select="."></xsl:variable> 
          <xsl:apply-templates select="//child[@eyes = 'black']" mode="child"> 
           <xsl:with-param name="obj" select="$obj"></xsl:with-param> 
          </xsl:apply-templates> 
         </xsl:for-each> 
        </xsl:for-each> 
       </table> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

deutete auf die child.xsl Datei:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template name="child"> 
     <xsl:param name="obj"></xsl:param> 
     <h3><xsl:text disable-output-escaping="yes">Child name</xsl:text> </h3> 
     <h4><xsl:value-of select="$obj/name"></xsl:value-of></h4> 
    </xsl:template> 
</xsl:stylesheet> 

Das erforderliche Ergebnis ist, nur einen Kindnamen zu sehen, der Ema ist, aber ich sehe Ema zweimal:

<html> 

<head> 
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"> 
    <title>Head first</title> 
</head> 

<body> 
    <table border="1"> 
    <tbody> 
     <tr> 
     <td>Name</td> 
     <td>Jordan</td> 
     </tr> 
     <tr> 
     <td>Age</td> 
     <td>25</td> 
     </tr> 
     Ema Ema 
    </tbody> 
    </table> 
</body> 

</html> 

Weiß jemand, warum das passiert?

+1

Warum deaktivieren Sie die Ausgabe bei einer einfachen Zeichenfolge wie "Name" oder "Alter", die trotzdem nicht maskiert werden muss? –

+0

Es gibt keinen Zweck, nur so geschrieben. Dies ist ein Beispiel für das echte Skriptproblem. –

Antwort

1

Der Grund ist, dass Sie über childs/child mit <xsl:for-each> iterieren und es gibt zwei <child> Elemente. Daher wird <xsl:apply-templates select="//child[@eyes = 'black']" mode="child"> zweimal ausgeführt und Sie erhalten zwei Ema s.

+0

macht es keinen Sinn. Ich habe eine Schleife und ich möchte nur das Element mit einem attr Augen = schwarz –

+0

Kannst du eine Lösung vorschlagen, die ich nur einmal das Filterkind sehen werde? –

+1

Ja. Entfernen Sie einfach die 'xsl: for-each'. Die 'xsl: apply-templates select =" // child ... "' selektiert bereits alle 'child' Elemente mit der Eigenschaft von black eyes. Es wendet Vorlagen auf _all_ 'child' Elemente mit dieser Eigenschaft an. – zx485