2009-11-19 82 views
0

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

<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语句只会导致测试真正的节点被显示。真的吗?

<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

的的xsl:for-每个嵌套在xsl:如果,但换每个不被如果限制。

我没有看到jNumber在您提供的XML中,但是您可以将for-each方面设置为与封闭方式相同的限制,以选择是否显示该区域。上述

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

行说: 开始与当前范围看产品 - 具有产品 - 其中有等于$ jNumber一个jNumber - 然后看看topicFocus节点。

1

Jason Aller的答案肯定是正确的,但我认为你有更多的机会来改进XSLT。无论你拥有的XPath,如:

select="products/product/topicFocus" 

你正在寻找所有products元素是上下文节点的子项(即您的模板正在改变,或者说你的for-each循环正在位于元素),然后他们的product儿童,以及其后的任何topicFocus儿童。这要么找到很多节点(如果上下文节点是您的products元素的父节点),要么根本没有节点(如果上下文节点是product元素,除非您的product元素有products子元素)。

如果您使用模板作为主要工具,使用XSLT会更容易。模板将节点转换为结果。在你的情况下,你想要将product节点转换成div。您还希望将topicFocustopicLeft元素转换为div s对。

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

<!-- 
    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> 

我已经简化了几个其他的东西在这里,太:

  • 因为在我看来好像除了设置display样式外,您的转换所发送的HTML元素topicFocustopicLeft是相同的,我为它们创建了单个模板。
  • 我在模板中使用了空格和缩进,以便HTML的结构很明显;这将使维护它变得更容易,并且不会影响变换如何产生输出。
  • 我已经删除了所有属性前的冗余./