Почему мой xslt отображает неправильные значения в моем выводе, даже если xpath правильный? - PullRequest
0 голосов
/ 06 октября 2018

Вот соответствующая часть моего XML-кода:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE recipeml SYSTEM "recipeml.dtd">
<recipeml>
  <recipe>
    <head>
        <title>Coq au Riesling</title>
    </head>
    <ingredients>
        <ing>
            <amt>
                <qty>30</qty>
                <unit system="metric">ml</unit>
            </amt>
            <item>garlic-infused olive oil</item>
        </ing>
        <ing>
            <amt>
                <qty>150</qty>
                <unit system="metric" unit="g">gram(s)</unit>
            </amt>
            <item>bacon lardons</item>
        </ing>
        <ing>
            <amt>
                <qty>1</qty>
            </amt>
            <item>leek(s)</item>
            <prep>(finely sliced)</prep>
        </ing>
        <ing>
            <amt>
                <qty>12</qty>
            </amt>
            <item>chicken thighs (boneless and skinned)</item>
        </ing>
        <ing>
            <amt>
                <qty>3</qty>
            </amt>
            <item>bay leaves</item>
        </ing>
        <ing>
            <amt>
                <qty>300</qty>
                <unit system="metric">gram(s)</unit>
            </amt>
            <item>oyster mushroom(s) (torn into strips)</item>
        </ing>
        <ing>
            <amt>
                <qty>750</qty>
                <unit system="metric">ml</unit>
            </amt>
            <item>Riesling</item>
        </ing>
        <ing>
            <amt>
                <qty> 1</qty>
                <unit>splash of</unit>
            </amt>
            <item>double cream (optional)</item>
        </ing>
        <ing>
            <amt>
                <qty> 1</qty>
                <unit>pinch of</unit>
            </amt>
            <item>salt</item>
        </ing>
        <ing>
            <amt>
                <qty>1</qty>
                <unit>pinch of </unit>
            </amt>
            <item>Pepper</item>
        </ing>
        <ing>
            <amt>
                <qty>1</qty>
                <unit>tablespoon(s)</unit>
            </amt>
            <item>dill (chopped to serve (2 tablespoons if needed)) </item>
        </ing>
    </ingredients>

Вот мой XSLT:

<xsl:template match="/">
    <html>
        <body>
            <xsl:apply-templates>

            </xsl:apply-templates>
        </body>          
    </html>
</xsl:template>
<xsl:template match="recipeml/recipe/head/title">
    <h3>
        <xsl:value-of select="."/>
    </h3>        
</xsl:template>
<xsl:template match="recipeml/recipe/ingredients">
    <ul> 
        <xsl:for-each select="ing">
            <li><xsl:value-of select="item"/>
                <ul><xsl:value-of select="//amt/child::qty[not(following-sibling::unit)]"/></ul></li>
        </xsl:for-each>
    </ul> 
</xsl:template>
<xsl:template match="recipeml/recipe/directions">
    <xsl:for-each select="*[not(preceding-sibling::step)]"/>
    <xsl:for-each select="*[not(following-sibling::note)]"/>
</xsl:template>

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

    <ul><xsl:value-of select="//amt/child::qty[not(following-sibling::unit)]"/></ul></li>

Вот вывод, который я получаю:

    <html>
      <body>  

  <h3>Coq au Riesling</h3>


  <ul>
     <li>garlic-infused olive oil
        <ul>1</ul>
     </li>
     <li>bacon lardons
        <ul>1</ul>
     </li>
     <li>leek(s)
        <ul>1</ul>
     </li>
     <li>chicken thighs (boneless and skinned)
        <ul>1</ul>
     </li>
     <li>bay leaves
        <ul>1</ul>
     </li>
     <li>oyster mushroom(s) (torn into strips)
        <ul>1</ul>
     </li>
     <li>Riesling
        <ul>1</ul>
     </li>
     <li>double cream (optional)
        <ul>1</ul>
     </li>
     <li>salt
        <ul>1</ul>
     </li>
     <li>Pepper
        <ul>1</ul>
     </li>
     <li>dill (chopped to serve (2 tablespoons if needed)) 
        <ul>1</ul>
     </li>
  </ul>

Что мне нужно изменить, чтобы оно показывало только сумму лука-порея, куриных бедер и лавровых листьев?

Ответы [ 2 ]

0 голосов
/ 06 октября 2018

Рассмотрите возможность корректировки вашей настройки с помощью шаблонов, которые идут по дереву ( рецепт уровень, ингредиенты уровень, ing уровень) и в конце применяются дваустанавливает для ing узлов.

При таком подходе вы избегаете сопоставления нескольких шаблонов из корня recipeml, использования xsl:foreach, использования following-sibling и абсолютных ссылок с //.И обязательно добавьте <xsl:strip-space>, чтобы удалить пробелы и разрывы строк из исходного XML.

<?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" indent="yes"/>
    <xsl:strip-space elements="*" />

    <xsl:template match="recipeml/recipe">
        <html>
            <body>
                <h3>
                    <xsl:value-of select="head/title"/>
                </h3>       
                <xsl:apply-templates select="ingredients"/>
            </body>          
        </html>
    </xsl:template>

    <xsl:template match="ingredients">
        <xsl:apply-templates select="ing[not(amt/unit)]"/>
        <xsl:apply-templates select="ing[amt/unit]"/>
    </xsl:template>

    <xsl:template match="ing[not(amt/unit)]">
        <ul> 
            <li><xsl:value-of select="item"/>
                <ul>
                    <xsl:value-of select="amt/qty"/>
                </ul>
            </li>
        </ul> 
    </xsl:template>

    <xsl:template match="ing[amt/unit]">
        <ul> 
            <li><xsl:value-of select="item"/>
            </li>
        </ul> 
    </xsl:template>

</xsl:stylesheet>

XSLT Fiddle Demo

0 голосов
/ 06 октября 2018

Выражение пути, начинающееся с "/" или "//", всегда выбирается из корня дерева.Вы пишете

<xsl:for-each select="ing">
   <li><xsl:value-of select="item"/>
       <ul><xsl:value-of select="//amt/child::qty[not(following-sibling::unit)]"/></ul></li>
</xsl:for-each>

, но amt является потомком ing, поэтому вы просто хотите select="amt/qty[...]".Вы также можете написать select="amt[not(unit)]/qty".

(Кстати, ваш вопрос содержит ключ к ответу. Корректное выражение XPath в одном контексте может быть совершенно неверным в другом. Понимание того, как XSLT изменяет узел контекстадля оценки выражения XPath критически важно.)

Кстати, ваше последнее правило шаблона:

<xsl:template match="recipeml/recipe/directions">
    <xsl:for-each select="*[not(preceding-sibling::step)]"/>
    <xsl:for-each select="*[not(following-sibling::note)]"/>
</xsl:template>

никогда не выдаст никакого вывода.Две xsl:for-each инструкции пусты, поэтому вы говорите «для каждого хххх, ничего не делать» - что всегда ничего не делает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...