测试XSLT中是否存在XML元素

时间:2009-10-28 21:10:56

标签: xml xslt

这可能是一个非常简单的答案,但对于我的生活,我无法理解。

我想显示某些内容,具体取决于正在显示的子元素,但我不知道如何测试我想要的元素。我想看看是否存在start,stop和note元素

<xsl:template match="protocol[@id=$protocolNumber]">
<h4><xsl:value-of select="$sectionNumber"/>.<xsl:value-of select="@id"/>&nbsp;<xsl:value-of select="@title"/></h4>
<p>
     <xsl:for-each select="child::*"> 
        <xsl:choose>
            <xsl:when test="start">
                <span id="start"><xsl:value-of select="start[@level]" /></span>
            </xsl:when>
            <xsl:when test="stop">
                <span id="stop"><xsl:value-of select="stop[@level]" /></span>
            </xsl:when>
            <xsl:when test="note">
                <span id="note"><xsl:value-of select="note[@title]" />:&nbsp;<xsl:value-of select="note/text()" /></span>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="text()"/><br/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each>
</p>

<protocol id="2" title="Post-Conversion Of VF / VT">
            <note title="criteria">Post-conversion treatment of VF or VT should only be started if the patient has regained a pulse of adequate rate, and has a supraventricular rhythm.  If not, refer to other cardiac protocols as appropriate.  All antiarrhythmics are  contraindicated if ventricular escape rhythm is present.</note>
            <start level="All Levels"/>
            <step>Routine medical care.</step>
            <stop level="EMT"/>
            <stop level="EMT-I"/>
            <start level="EMT-CC &amp; P"/>
            <step>
                If conversion results from defibrillation without any drug therapy:<br/><br/>
                Amiodarone (Cordarone) 150 mg IV/IO Slow IV
            </step>
            <step>If Amiodarone was the drug resulting in conversion from VF/VT, no additional antiarrhythmic is required.</step>
            <step>
                If Lidocaine (Xylocaine) was the drug resulting in conversion from VF/VT:<br/><br/>
                Repeat Lidocaine bolus 0.75 mg/kg IV/IO every 10 minutes up to a total cumulative dose of 3 mg/kg.
            </step>
            <step>If more than above listed doses are needed because of length of transport time, contact Medical Control.</step>
        </protocol>

2 个答案:

答案 0 :(得分:5)

xsl:for-each内,上下文元素.是您正在迭代的当前元素。当您编写像start这样的XPath表达式时,它实际上与child::start相同。你想要的是self::start。另请注意,child::*是多余的 - 只需*即可。

更惯用的XSLT方法是将其重构为一组单独的模板,让模式匹配完成其工作:

<xsl:template match="protocol[@id=$protocolNumber]">
  <h4><xsl:value-of select="$sectionNumber"/>.<xsl:value-of select="@id"/>&nbsp;<xsl:value-of select="@title"/></h4>
  <p>
    <!-- Applies templates to all child elements -->
    <xsl:apply-templates/>
  </p>
</xsl:template>

<xsl:template match="protocol/start">
  <span id="start"><xsl:value-of select="start/@level" /></span>
</xsl:template>

<xsl:template match="protocol/stop">
  <span id="stop"><xsl:value-of select="stop/@level" /></span>
</xsl:template>

<xsl:template match="protocol/note">
  <span id="note"><xsl:value-of select="note/@title" />:&nbsp;<xsl:value-of select="note" /></span>
</xsl:template>

<xsl:template match="protocol/*">
   <xsl:value-of select="."/>
</xsl:template>

答案 1 :(得分:1)

我不确定你要做什么,但我看到了一些可能的问题:

首先,你使用<xsl:choose />构造,这意味着如果你有“开始”没有“停止”和“注意”将被处理(你可能想要使用普通的<xsl:if />代替,或者无论所希望的逻辑表明什么。

其次,当您使用start@level时,我相信您的意思是start/@level