html 用于递归XML元素的XSLT

mlmc2os5  于 2023-01-07  发布在  其他
关注(0)|答案(3)|浏览(129)

我正在研究游泳程序的XML标准,我创建了一个XML schema and some example XML files,因为游泳程序经常使用重复(例如:4 x 100米自由泳),我创建了一个XML元素<instruction>,它可以包含自身的更多示例。(例如4 x)或直接游泳指令(100米自由泳)。<repetition>可以包含进一步的重复和/或直接游泳指令。下面是一个示例XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<program xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="file:/Users/cba56/Dropbox%20(UC%20Enterprise)/swimML/oxygen/swiML.xsd">

    <!-- Complex program with repetitions and loops -->

    <title>Complex Program</title>
    <author>
        <firstName>Christoph</firstName>
        <lastName>Bartneck</lastName>
        <email>christoph@bartneck.de</email>
    </author>
    <author>
        <firstName>Matthias</firstName>
        <lastName>MccCurdy</lastName>
        <email>mc@swim.com</email>
    </author>
    <creationDate>2022-06-30</creationDate>
    <poolLength>25</poolLength>
    <poolLengthUnit>meters</poolLengthUnit>
    <defaultInstructionLengthUnit>meters</defaultInstructionLengthUnit>

    <!-- Examples of a veriety of instructions -->

    <instruction>
        <lengthAsDistance>100</lengthAsDistance>
        <rest><afterStop>PT20S</afterStop></rest>
        <intensity><staticIntensity>
                <precentageEffort>70</precentageEffort>
            </staticIntensity></intensity>
        <stroke><standardStroke>freestyle</standardStroke></stroke>
        <equipment>pads</equipment>
        <equipment>pullBuoy</equipment>
    </instruction>
    <instruction>
        <lengthAsDistance>100</lengthAsDistance>
        <rest><sinceStart>PT1M45S</sinceStart></rest>
        <intensity><staticIntensity>
                <precentageEffort>70</precentageEffort>
            </staticIntensity></intensity>
        <stroke><kicking>
                <orientation>front</orientation>
                <legMovement>flutter</legMovement>
            </kicking></stroke>
    </instruction>
    <instruction>
        <lengthAsDistance>400</lengthAsDistance>
        <rest><inOut>3</inOut></rest>
        <intensity>
            <startIntensity>
                <precentageEffort>60</precentageEffort>
            </startIntensity>
            <stopIntensity>
                <precentageEffort>100</precentageEffort>
            </stopIntensity>
        </intensity>
        <stroke><standardStroke>freestyle</standardStroke></stroke>
    </instruction>

    <!-- An example of a simple repetition -->
    <!-- It uses IM as the repetition stroke, so 100FL, 100BK, 100BR, 100FR -->
    <instruction>
        <repetition>
            <repetitionCount>4</repetitionCount>
            <stroke><standardStroke>individualMedley</standardStroke></stroke>
            <instruction>
                <lengthAsDistance>100</lengthAsDistance>
                <rest><sinceStart>PT1M45S</sinceStart></rest>
                <intensity><staticIntensity>
                        <zone>tempo</zone>
                    </staticIntensity></intensity>
            </instruction>
        </repetition>
    </instruction>

    <!-- Example of a repeition changing intensity.  -->
    <!-- This would be a build exercise -->
    <instruction>
        <repetition>
            <repetitionCount>4</repetitionCount>
            <intensity>
                <startIntensity>
                    <precentageEffort>60</precentageEffort>
                </startIntensity>
                <stopIntensity>
                    <precentageEffort>100</precentageEffort>
                </stopIntensity>
            </intensity>
            <instruction>
                <lengthAsDistance>100</lengthAsDistance>
                <stroke><standardStroke>freestyle</standardStroke></stroke>
                <breath>5</breath>
            </instruction>
        </repetition>
    </instruction>

    <!-- Exmaple of a repeition inside a repetition -->
    <instruction>
        <repetition>
            <repetitionCount>4</repetitionCount>
            <instruction>
                <repetition>
                    <repetitionCount>2</repetitionCount>
                    <instruction>
                        <lengthAsDistance>50</lengthAsDistance>
                        <stroke><standardStroke>backstroke</standardStroke></stroke>
                    </instruction>
                    <instruction>
                        <lengthAsDistance>50</lengthAsDistance>
                        <stroke><standardStroke>breaststroke</standardStroke></stroke>
                    </instruction>
                </repetition>
            </instruction>
            <instruction>
                <lengthAsDistance>200</lengthAsDistance>
                <stroke><standardStroke>freestyle</standardStroke></stroke>
            </instruction>
        </repetition>
    </instruction>

    <!-- some basic instructions -->
    <instruction>
        <lengthAsTime>PT2M30S</lengthAsTime>
        <lenghUnit>time</lenghUnit>
        <stroke><standardStroke>freestyle</standardStroke></stroke>
    </instruction>
    <instruction>
        <lengthAsTime>PT1M30S</lengthAsTime>
        <stroke><standardStroke>freestyle</standardStroke></stroke>
    </instruction>
    <instruction>
        <lengthAsDistance>8</lengthAsDistance>
        <lenghUnit>laps</lenghUnit>
        <intensity><staticIntensity>
                <zone>endurance</zone>
            </staticIntensity></intensity>
        <stroke><standardStroke>backstroke</standardStroke></stroke>
    </instruction>
</program>

我现在尝试使用XSLT将instance1.xml转换为类似goal.xhtml的内容。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Complex Program</title>
    </head>
    <body>
        <h1>Complex Program</h1>
        <h2>Description:</h2>
        <p></p>
        <p>Target Pool Length: 25 meters</p>
        <p>Default Length Unit: meters</p>
        <p>Creation Date: 30 June 2022</p>
        <h2>Authors:</h2>
        <ul>
            <li>Christoph Bartneck, christoph@bartneck.de</li>
            <li>Matthias MccCurdy, </li>
        </ul>
        <h2>Program:</h2>
        <ul>
            <li>100 FR w20 70% Pads and Pullboy</li>
            <li>100 Kick Front Flutter @1:45 70%</li>
            <li>400 FR 3nd in 1st out 60%</li>
            <li>4x IM <ul>
                    <li>100 @1:45 Tempo</li>
                </ul>
            </li>
            <li>4x build 60%-100% <ul>
                    <li>100 FR b5</li>
                </ul>
            </li>
            <li>4x <ul>
                    <li>2x <ul>
                            <li>50 BK</li>
                            <li>50 BR</li>
                        </ul>
                    </li>
                    <li>200 FR</li>
                </ul>
            </li>
            <li>2:30 FR</li>
            <li>8L BK Endurance</li>
        </ul>
    </body>
</html>

虽然我能够进行基本的XSLT转换(例如<author>),但我一直在为XML Schema和<instruction> '元素的递归性质而挣扎,我甚至无法找到解决方案。
有没有人可以看一下XML文件示例,并提出XSLT转换的策略?

s3fp2yjn

s3fp2yjn1#

XSLT中处理递归XML结构(即可以包含相同类型的其他元素的元素)的一般策略是使用模板匹配。您将创建一个与相关元素匹配的模板(例如<xsl:template match="instruction">);然后,模板产生一些输出,并且还使用xsl:apply-templates来处理子元素,这(假设存在相同类型的子元素)实际上是对相同模板的递归调用。

ef1yzkbh

ef1yzkbh2#

强化@ConalTuohy的答案,XSLT样式表的标准设计模式处理递归时甚至不需要考虑它。问问自己“当我遇到instruction元素时,我需要做什么?",答案可能是类似“生成一个ul元素,其子元素为li元素。"

<xsl:template match="instruction">
 <ul>
   <xsl:for-each select"child::node()">
     <li><xsl:apply-templates select="."/></li.
   </xsl:for-each>
 </ul>
</xsl:template>

注意:这个答案与“我如何开始”这个一般性问题有关,我还没有详细研究过你的输入和输出。

8i9zcol2

8i9zcol23#

解决了。这个应该能解决问题:

<xsl:template match="instruction">
    <xsl:apply-templates select="repetition"/>
    <xsl:apply-templates select="lengthAsDistance"/>
    <xsl:apply-templates select="lengthAsTime" />
</xsl:template>

<xsl:template match="repetition">
    <li>Repetition Count: <xsl:value-of select="repetitionCount"/></li>
    <ol>
        <xsl:apply-templates select="instruction"/>
    </ol>
</xsl:template>

相关问题