xpath с xsl: когда тест - PullRequest
       3

xpath с xsl: когда тест

0 голосов
/ 02 января 2019

Мне нужно отобразить БОЛЬШОЙ на планетах с диаметром выше среднего диаметра или МАЛЕНЬКИМ без использования функции avg (XSLT 1.0)

Я пытался использовать xsl: когда с условием типа диаметр> сумма (....) div count (nom), но это не работает:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="/systeme_solaire">
    <html lang="fr">
        <head>
            <title>Les planètes</title>
        </head>
        <body>
            <xsl:apply-templates select="planete[nom!='Terre']">
                <xsl:sort select ="diametre" order="descending" data-type="number" />
            </xsl:apply-templates>
        </body>
    </html>
</xsl:template> 

<xsl:template match="planete" >
    <ul>
        <p><b><xsl:value-of select="nom"/> : </b></p>
        <li>Distance au soleil: <xsl:value-of select="distance"/><xsl:value-of select="distance/@unit"/></li>
        <li>Masse: <xsl:value-of select="masse"/> <xsl:value-of select="masse/@unit"/></li>
        <li>
<xsl:choose>
  <xsl:when test="diametre > ((sum(diametre[unit='diamètre terrestre']*sum(diametre[unit='km']))+sum(diametre[unit='km'])) div count(nom))">
   BIG
  </xsl:when>
  <xsl:otherwise>
   SMALL
  </xsl:otherwise>
</xsl:choose>  Diamètre: <xsl:value-of select="diametre"/> <xsl:value-of select="diametre/@unit"/></li>
        <xsl:if test="satellite>0"><li>Nombre de satellites: <xsl:value-of select="satellite"/></li></xsl:if>
    </ul>
</xsl:template>

</xsl:stylesheet>

Используемый XML-файл (диаметр планет, отличных от Земли, определяется в соответствии с соотношением диаметров Земли):

<?xml version="1.0" encoding="ISO-8859-1" ?>
 
<systeme_solaire>
 
<planete type="tellurique">
    <nom>Vénus</nom>
    <distance unit="UA" >0.7</distance>
    <masse unit="masse terrestre">0.8</masse>
    <diametre unit="diamètre terrestre">0.9</diametre>
</planete>
 
<planete type="tellurique">
    <nom>Terre</nom>
    <distance unit="km" >149600000</distance>
    <masse unit="kg">5.98e24</masse>
    <diametre unit="km">12756</diametre>
    <satellite>1</satellite>
</planete>
 
<planete type="tellurique">
    <nom>Mars</nom>
    <distance unit="UA" >1.5</distance>
    <masse unit="masse terrestre">0.1</masse>
    <diametre unit="diamètre terrestre">0.5</diametre>
    <satellite>2</satellite>
</planete>
 
</systeme_solaire>

1 Ответ

0 голосов
/ 02 января 2019

У вас есть две проблемы:

  1. Сначала вам нужно рассчитать свой средний диаметр вне шаблона planete, чтобы охватить все планеты, а затем передать это среднее значение шаблону
  2. Тогда у вас неправильный xpath: неправильная скобка, unit - это атрибут, поэтому вам нужно использовать @.Вам нужно что-то вроде этого:
    ((sum(//diametre[@unit='diamètre terrestre'])*//diametre[@unit='km'])+//diametre[@unit='km']) div count(//nom)
    Редактировать : вам также нужно рассчитать фактический диаметр вашей текущей планеты на основании диаметра Земли, вы можете сделать это, добавив еще один параметр <xsl:with-param name="terre" select="//diametre[@unit='km']"/> и используя его <xsl:when test="diametre*$terre > $avg">

Я обновил вам XSLT примерно так:

Решение 1

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="/systeme_solaire">
    <html lang="fr">
        <head>
            <title>Les planètes</title>
        </head>
        <body>
            <xsl:apply-templates select="planete[nom!='Terre']">
                <xsl:sort select ="diametre" order="descending" data-type="number" />
                <xsl:with-param name="avg" select="((sum(//diametre[@unit='diamètre terrestre'])*//diametre[@unit='km'])+//diametre[@unit='km']) div count(//nom)"/>
                <xsl:with-param name="terre" select="//diametre[@unit='km']"/>
            </xsl:apply-templates>
        </body>
    </html>
</xsl:template> 

<xsl:template match="planete" >
   <xsl:param name="avg"/>
   <xsl:param name="terre"/>
    <ul>
        <p><b><xsl:value-of select="nom"/> : </b></p>
        <li>Distance au soleil: <xsl:value-of select="distance"/><xsl:value-of select="distance/@unit"/></li>
        <li>Masse: <xsl:value-of select="masse"/> <xsl:value-of select="masse/@unit"/></li>
        <li>
<xsl:choose>
  <xsl:when test="diametre*$terre > $avg">
   BIG
  </xsl:when>
  <xsl:otherwise>
   SMALL
  </xsl:otherwise>
</xsl:choose>  Diamètre: <xsl:value-of select="diametre"/> <xsl:value-of select="diametre/@unit"/></li>
        <xsl:if test="satellite>0"><li>Nombre de satellites: <xsl:value-of select="satellite"/></li></xsl:if>
    </ul>
</xsl:template>

</xsl:stylesheet>

Изменить , чтобы добавить предложение Майкла (рассчитать средний диаметр как отношение):
Решение 2

<xsl:apply-templates select="planete[nom!='Terre']">
    <xsl:sort select ="diametre" order="descending" data-type="number" />
    <xsl:with-param name="avg" select="(sum(//diametre[@unit='diamètre terrestre'])+1) div count(//nom)"/>
</xsl:apply-templates>
...
<xsl:template match="planete" >
   <xsl:param name="avg"/>
   ...
     <xsl:when test="diametre > $avg">
   ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...