列表元素的后继兄弟

时间:2018-10-23 12:43:42

标签: html xml xslt xpath

我想创建一个列表项,其格式正确无误。但是,我想将字符串“ ”添加到替代项中。 我的XPath控件无法正常工作。如果我有一个List和一个基础SmallList,该函数将被忽略。 如果列表不存在,则一切正常。但是,我的表达方式不正确,希望您能对我有所帮助。我正在使用XSLT 1.0。 我希望这个例子是可以理解的。

XML:

<University>
    <Class>
        <Student>John Doe</Student>
        <List>
            <SmallList>
                <Student>Jane Doe</Student>
            </SmallList>
        </List>
    </Class>
    <AlternativeClass>
        <Class>
            <Student>Richard Roe</Student>
        </Class>
    </AlternativeClass>
</University>

结果应如下所示:

<div>
   <p data-role="heading">University-Heading</p>
   <ul>
      <li>John Doe
         <ul>
            <li>Jane Doe</li>
         </ul>
      </li>
      <li class="parablock bold_">or</li>
      <li>Richard Roe</li>
   </ul>
</div>

我提到<li class="parablock bold_>or<li>丢失了。 如果我想删除List-Block,结果看起来像预期的那样(例如,本例中的Jane Doe)。

<div>
   <p data-role="heading">University-Heading</p>
   <ul>
      <li>John Doe</li>
      <li class="parablock bold_">or</li>
      <li>Richard Roe</li>
   </ul>
</div>

以下兄弟姐妹的构造应如下所示(BBB的兄弟姐妹应为XXX):

<AAA>
    <BBB>
        <CCC/>
    </BBB>
    <XXX>
        <DDD/>
        <EEE/>
    </XXX>
</AAA>

我的XSLT看起来像这样:

<xsl:template match="University">
    <div>
        <!-- HEADING FOR UNIVERSITY -->
        <p data-role="heading">
            <xsl:text>University-Heading</xsl:text>
        </p>
        <ul>
            <xsl:apply-templates/>
        </ul>
    </div>
</xsl:template>
<!-- CLASS -->
<xsl:template match="Class">
    <xsl:apply-templates/>
    <!-- 'OR' BEFORE ALTERNATIVE CLASS -->
    <!-- I GUESS THAT THE MISTAKE IS IN HERE -->
    <xsl:if test="following-sibling::*[1][self::AlternativeClass]">
        <li class="parablock bold_">
            <xsl:text>or</xsl:text>
        </li>
    </xsl:if>
</xsl:template>
<!-- CLASS-NODE WITH LIST -->
<xsl:template match="Class[List]">
    <xsl:apply-templates select="Student"/>
</xsl:template>
<!-- ALTERNATIVECLASS -->
<xsl:template match="AlternativeClass">
    <xsl:apply-templates/>
</xsl:template>
<!-- STUDENT IN CLASS AND SMALLLIST -->
<xsl:template match="SmallList/Student | Class/Student">
    <li>
        <xsl:if test="name(preceding-sibling::*[1]) = 'Para'">
            <xsl:attribute name="class">parablock</xsl:attribute>
        </xsl:if>
        <xsl:apply-templates/>
        <xsl:apply-templates select="following-sibling::*[1][self::List]"/>
    </li>
</xsl:template>
<!-- LIST -->
<xsl:template match="List">
    <ul>
        <xsl:apply-templates/>
    </ul>
</xsl:template>
<!-- SMALLLIST -->
<xsl:template match="SmallList">
    <xsl:apply-templates/>
</xsl:template>

.NET XSLT小提琴:https://xsltfiddle.liberty-development.net/bdxtqV

1 个答案:

答案 0 :(得分:2)

您对以下兄弟姐妹的陈述实际上是正确的。问题是确实有以下Class的{​​{1}}也有一个子AlternativeClass元素,这意味着它被此模板匹配(因为它具有额外的条件,模板的优先级更高)

List

由于没有下面的同级检查,因此不会创建您期望的输出。

您也可以在此语句中添加条件

<xsl:template match="Class[List]">
    <xsl:apply-templates select="Student"/>
</xsl:template>

尽管这是一些代码重复,但是您可以将该逻辑放在命名模板中,或者也可以将两个“ Class”模板合并为一个...

<xsl:template match="Class[List]">
    <xsl:apply-templates select="Student"/>
    <xsl:if test="following-sibling::*[1][self::AlternativeClass]">
        <li class="parablock bold_">
            <xsl:text>or</xsl:text>
        </li>
    </xsl:if>
</xsl:template>