2013-05-16 2 views
0

Я работаю с преобразованием XSL на следующий HTML:XSLT: набор классов на основе элементов потомков

<div id="context"> 
    <p>Sometimes, there is content here.</p> 
</div> 

<div id="main-content"> 
    <p>There is always content here.</p> 
</div> 

<div id="related"> 
    <img src="CMS PREVIEW ICON - ADMIN ONLY"/> 
    <p>Sometimes, there is content here.</p> 
    <p>The image is always the first child only if the user is inside the CMS, but it should be ignored if there is not other content present.</p> 
</div> 

В настоящее время я пытаюсь настроить атрибут класса на main-content DIV и related DIV , в зависимости от того, есть ли у related один из потомков (это не значок CMS). Вот что у меня есть:

<xsl:template match="div[@id='main-content']"> 
    <xsl:copy> 
     <!-- copy the current body node contents --> 
     <xsl:attribute name="class"> 
      <xsl:choose> 
       <xsl:when test="//div[@id='related']/descendant::* and name(//div[@id='related']/*[1]) != 'img' or count(//div[@id='related']/descendant::* > 1) and name(//div[@id='related']/*[1]) != 'img'">span6</xsl:when> 
       <!-- left nav but no right col --> 
       <xsl:when test="not(//div[@id='related']/descendant::*) or (count(//div[@id='related']/descendant::* = 1) and name(//div[@id='related']/*[1]) = 'img')">span9</xsl:when>      
       <!-- no left nav and populated right col --> 
       <xsl:when test="//div[@id='related']/descendant::* and (count(//div[@id='related']/descendant::* = 1) and name(//div[@id='related']/*[1]) != 'img') and not(//div[@class='data-entry wide'])">span9</xsl:when>      
       <xsl:otherwise>span12</xsl:otherwise> 
      </xsl:choose> 
     </xsl:attribute> 
     <xsl:apply-templates select="@*|node()"/> 
     <!-- output the rest --> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="div[@id='related']"> 
    <xsl:copy> 
     <!-- copy the current body node contents --> 
     <xsl:attribute name="class"> 
      <xsl:choose> 
       <xsl:when test="count(* = 0) or (count(* = 1) and name(*[1]) = 'img')">hidden</xsl:when> 
       <xsl:when test="descendant::*">span3</xsl:when> 
       <xsl:otherwise>hidden</xsl:otherwise> 
      </xsl:choose> 
     </xsl:attribute> 
     <xsl:apply-templates select="@*|node()"/> 
     <!-- output the rest --> 
    </xsl:copy> 
</xsl:template> 

И затем, если related дается класс скрытый, я удалить его позже, так что он не занимает полосу пропускания, DOM пространства и т.д.

Я эту мысль будет работать правильно, поскольку он, похоже, получает правильные значения в xpath, но он просто не удаляет такие элементы, как должен. Это немного странно, так как мне нужно знать:

  1. Есть ли потомки в related для взглядов, которые не внутри CMS
  2. И, взглядов внутри CMS, которые есть потомки, которые не являются конкретное изображение (другие изображения всегда будут обернуты в div, ссылку и т. д.)

Любые мысли?

Спасибо, Jonathan

+0

С одной стороны, 'count (* = 0)' недействителен XPath. 'count (*) = 0' будет правильным способом сделать это, но вам лучше использовать' not (*) '. Аналогично для 'count (* = 1)' вы можете использовать 'not (* [2])'. У меня возникли проблемы с расшифровкой первого набора '' s. Не могли бы вы разбить их для нас? – JLRishe

ответ

2

Даже если я не совсем уверен, что если у меня есть правильное понимание вашего запроса, я дам ему попробовать.

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 

     <xsl:template match="div[@id='main-content']"> 
    <xsl:copy> 
     <!-- copy the current body node contents --> 
     <xsl:attribute name="class"> 
      <xsl:choose> 
       <!-- "related" has any descendants (that are not the CMS icon). --> 
       <xsl:when test="//div[@id='related']/* and 
          count(//div[@id='related']/img) != count(//div[@id='related']/*) ">span6</xsl:when> 
       <xsl:otherwise>span9</xsl:otherwise> 
      </xsl:choose> 
     </xsl:attribute> 
     <xsl:apply-templates select="@*|node()"/> 
     <!-- output the rest --> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="div[@id='related']"> 
    <xsl:copy> 
     <!-- copy the current body node contents --> 
     <xsl:apply-templates select="@*"/> 
     <xsl:choose> 
       <!-- it should be ignored if there is not other content present --> 
       <xsl:when test=" count(img) = count(*)"> 
        <xsl:attribute name="class">hidden</xsl:attribute> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:attribute name="class">span3</xsl:attribute> 
        <xsl:apply-templates select="node()"/> 

       </xsl:otherwise> 
      </xsl:choose> 
     <!-- output the rest --> 
    </xsl:copy> 
</xsl:template> 

    <xsl:template match="node() | @*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node() | @*" /> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Это работало фантастически для меня; большое спасибо. –

Смежные вопросы