仅从一个节点提取内容

时间:2009-11-19 23:13:42

标签: xml xslt xpath

我正在尝试从我的xml文档中提取特定节点,但继续从所有节点获取内容。我通过将数字传递给带有片段调用($ jNumber)的变量集中的xslt来测试特定的jNumber。

<xsl:if test="products/product/jNumber[. = $jNumber]">
    <div class="floatLeft padTop10 margLeft10" style="width:185px;">
        <xsl:for-each select="products/product/topicFocus">
            <div id="tab{./@tab}focus" class="linksUnit padBtm3" style="display:block;"><xsl:text>» </xsl:text><a href="#" class="bold" target="_blank"><em><xsl:value-of select="./@name" /></em></a></div>
            <div id="tab{./@tab}ready" class="linksUnit padBtm3" style="display:none;"><xsl:text>» </xsl:text><a href="#" target="_blank"><xsl:value-of select="./@name" /></a></div>
        </xsl:for-each>
        <xsl:for-each select="products/product/topicLeft">
            <div id="tab{./@tab}focus" class="linksUnit padBtm3" style="display:none;"><xsl:text>» </xsl:text> <a href="#" class="bold" target="_blank"><em><xsl:value-of select="./@name" /></em></a></div>
            <div id="tab{./@tab}ready" class="linksUnit padBtm3" style="display:block;"><xsl:text>» </xsl:text><a href="#" target="_blank"><xsl:value-of select="./@name" /></a></div>
        </xsl:for-each>
    </div>
</xsl:if>

据我所知,if语句只会导致显示测试为true的节点。这是真的吗?

<products>
    <product>
        <jNumber>1234</jNumber>
        <name>Product #1</name>
        <numberoftabs>12</numberoftabs>
        <!-- Links at top of the page -->
        <topicFocus tab="1" name="Accessories"></topicFocus>
        <!--topicLeft tab="2" name="Configuration examples"></topicLeft-->
        <topicLeft tab="2" name="Resources (white papers, datasheets, etc.)"></topicLeft>
        <topicLeft tab="3" name="Download software"></topicLeft>
        <topicLeft tab="4" name="FAQs"></topicLeft>
        <topicLeft tab="5" name="Interoperability"></topicLeft>
        <!--topicLeft tab="6" name="MIBs"></topicLeft-->
        <topicRight tab="6" name="Technical documentation">
            <subCategory tab="7">Management and Configuration</subCategory>
            <subCategory tab="8">Archived</subCategory>
        </topicRight>
        <topicRight tab="9" name="Related links"></topicRight>
        <topicRight tab="10" name="Support form"></topicRight>
    </product>
</products>    

2 个答案:

答案 0 :(得分:2)

xsl:for-each嵌套在xsl:if中,但for-each不受if的限制。

我没有看到你提供的XML中jNumber的位置,但你可以使for-each方面的限制与封闭的相同,如果选择显示该区域的话。

<xsl:for-each select="products/product[jNumber = $jNumber]/topicFocus">

上面的一行说: 从当前范围开始寻找产品 - 其产品 - jNumber等于$ jNumber - 然后查看topicFocus节点。

答案 1 :(得分:1)

Jason Aller的回答当然是正确的,但我认为你有更多的机会来改进XSLT。无论你在哪里都有XPath:

select="products/product/topicFocus"

您正在查看作为上下文节点的子项的所有products元素(即模板正在转换的元素,或者您的for-each循环当前所在的元素),然后是它们的{ {1}}孩子,然后是下面的任何product个孩子。那要么找到​​很多节点(如果上下文节点是你的topicFocus元素的父节点),要么根本没有(如果上下文节点是products元素,除非你的{{1} } element有product个孩子)。

如果您使用模板作为主要工具,使用XSLT要容易得多。模板将节点转换为结果。在您的情况下,您希望将product个节点转换为products个。您还希望将productdiv元素转换为topicFocus对。

如果模板的设计反映了这一点,它看起来像这样:

topicLeft

我也在这里简化了其他一些事情:

  • 因为它看起来好像你的转换为div<!-- this, somewhere in the main template, finds the specific product element you're looking for and transforms it. --> <xsl:apply-templates select="products/product[jNumber = $jNumber]/> <xsl:template match="product"> <div class="floatLeft padTop10 margLeft10" style="width:185px;"> <xsl:apply-templates select="topicFocus"/> <xsl:apply-templates select="topicLeft"/> </div> </xsl:template> <xsl:template match="topicFocus | topicLeft"> <xsl:variable name="display1"> <xsl:choose> <xsl:when test="name() = 'topicFocus'>none</xsl:when> <xsl:otherwise>block</xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="display2"> <xsl:choose> <xsl:when test="name() = 'topicFocus'>block</xsl:when> <xsl:otherwise>none</xsl:otherwise> </xsl:choose> </xsl:variable> <div id="tab{@tab}focus" class="linksUnit padBtm3" style="display:{$display1};"> <xsl:text>» </xsl:text> <a href="#" class="bold" target="_blank"> <em> <xsl:value-of select="@name" /> </em> </a> </div> <div id="tab{@tab}ready" class="linksUnit padBtm3" style="display:{$display2};"> <xsl:text>» </xsl:text> <a href="#" target="_blank"> <xsl:value-of select="@name" /> </a> </div> </xsl:template> 元素发送的HTML是相同的,除了topicFocus样式的设置方式,我创建了一个他们的模板。
  • 我在模板中使用了空格和缩进,以便HTML的结构明显;这将使维护它变得更容易,并且对转换如何产生输出没有影响。
  • 我删除了您在所有属性前面的冗余topicLeft