Получить значение дочерних узлов в XSLT - PullRequest
0 голосов
/ 09 января 2019

Я очень новичок в XML и XSLT, но я пытаюсь создать HTML-страницу, которая проходит по циклам различной длины и создает список в HTML.

XML выглядит примерно так:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <module>
        <name ID="SDCModule002">
            <role>SDC</role>
            <modNum>002</modNum>
            <title>Test</title>
            <audience>me</audience>
            <numSteps>7</numSteps>
            <steps>
                <step1>Do this 1</step1>
                <step2>Do this 2</step2>
                <step3>Do this 3</step3>
                <step4>Do this 4</step4>
                <step5>Do this 5</step5>
                <step6>Do this 6</step6>
                <step7>Do this 7</step7>
            </steps>
        </name>
        <name ID="SDCModule003">
            <role>SDC</role>
            <modNum>003</modNum>
            <title>Hi</title>
            <audience>you</audience>
            <numSteps>4</numSteps>
            <steps>
                <step1>Hi</step1>
                <step2>There</step2>
                <step3>You</step3>
                <step4>Guys</step4>
            </steps>
        </name>
    </module>
</xml>

У меня так, что информация, такая как Название, аудитория, задача и т. Д., Отображается для модуля, который я ищу, чтобы он работал.

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

<xsl:template match="/xml">
<html>
<head>
<title><xsl:value-of select="module/name[@ID='SDCModule001']/title "/></title>
</head>

<xsl:apply-templates select="module/name[@ID='SDCModule001']"/>

</body> 
</html> 
</xsl:template> 

<xsl:template name="stepList" match="name">


<div id= "info">
<center>

<font face="verdana" size="2"><b><center><xsl:value-of select="title" /></center></b></font>
<hr></hr>

<xsl:value-of select="audience" />
<p></p>
<xsl:value-of select="numSteps" />

</center>

</div>

</xsl:template>


</xsl:stylesheet>

Я думаю, мне нужно иметь <xsl:for-each>, в котором перечислены шаги в упорядоченном списке, поэтому у SDCModule002 будет 7 шагов, а у SDCModule003 будет только 4, или я просто получу значения всех дочерних узлов родительского элемента <steps>

Я не хочу делать 15, если в заявлениях говорится: «если numSteps равно 1, то делайте это ... если numSteps равно 2, то делайте это» и т.д. уверен, что есть более эффективный способ сделать это.

Отредактировано

Ожидаемые результаты будут такими:

Модуль: SCDModule001 Название: Тест Аудитория: я шаги: 1. Сделай это 1 2. Сделай это 2 3. Сделай это 3 4. Сделай это 4 6. Сделай это 5 7. Сделай это 6 8. Сделай это 7

Ответы [ 2 ]

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

Как правило, вы должны избегать использования xsl: for-each, когда он не нужен. Хотя это не имеет большого значения для производительности, для небольших переводов или проектов. Дополнительным преимуществом apply-templates является то, что вам нужно изменять только xpath, если ввод изменяется во время реализации.

Вот пример, который создает 2 html-файла на модуль. Шаблон, который соответствует «шагам», является дополнительным, вам не нужно, чтобы он работал.

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

<xsl:template match="/xml">
    <xsl:apply-templates select="module/name"/>
</xsl:template>
<!--Each name is a file - but can easily changed to module -->
<xsl:template match="name">
    <html>
        <head>
            <title>***<xsl:value-of select="@ID"/>***</title>
        </head>
        <body>
            <div id= "info">
                <center>
                    <font face="verdana" size="2">
                        <b>
                            <center>
                                <xsl:value-of select="title" />
                            </center>
                        </b>
                    </font>
                    <hr />
                    <xsl:value-of select="audience" />
                    <p></p>
                    <xsl:apply-templates select="steps"/>
                </center>
            </div>
        </body>
    </html>
</xsl:template>

<!--Extra match for styling - steps can also directly be called from "name" template-->
<xsl:template match="steps">
    <xsl:value-of select="numSteps" />
    <ol>
        <xsl:apply-templates select="node()" mode="steps"/>
    </ol>
</xsl:template>

<!--Wildcard - matches all step nodes-->
<xsl:template match="*" mode="steps">
    <li><xsl:value-of select="." /></li>
</xsl:template>

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

Включение xsl:for-each над элементами step? может выглядеть следующим образом. Я также изменил некоторые xsl:apply-templates, чтобы показать все module/name s в выводе. Вывод не очень, но должен дать вам хорошее начало. Не забудьте добавить

<?xml-stylesheet href="test.xslt" type="text/xsl" ?>

строка вашего XML для запуска в браузере.

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

<xsl:template match="text()" />

<xsl:template match="/xml">
    <html>
        <head>
            <title>***<xsl:value-of select="module/name[@ID='SDCModule002']/title "/>***</title>
        </head>
        <body>
            <xsl:apply-templates select="module/name"/>
        </body> 
    </html> 
</xsl:template> 

<xsl:template match="steps">
    <div id= "info">
        <center>
            <font face="verdana" size="2">
                <b>
                    <center>
                        <xsl:value-of select="../title" />
                    </center>
                </b>
            </font>
            <hr />
            <xsl:value-of select="../audience" />
            <p></p>
            <xsl:value-of select="../numSteps" />
            <ol>
                <xsl:for-each select="*">
                    <li><xsl:value-of select="." /></li>
                </xsl:for-each>
            </ol>
        </center>
    </div>
</xsl:template>

</xsl:stylesheet>

В Firefox вывод выглядит так:

Output image

...