xslt 1.0 - 尝试获取特定值的节点

时间:2013-08-20 17:17:46

标签: xslt xslt-1.0

我有一个XML文件,它有许多类似命名的节点,但某些节点中的属性是唯一的。我想只输出属于某个属性值的节点的HTML页面。

这是xml:

<document>
  <component>
    <section>
      <templateId value="temp_1" />
      <entry>
        <act>
          <code displayName="temp_1:code_1" />
        </act>
      </entry>
      <entry>
        <act>
          <code displayName="temp_1:code_2" />
        </act>
      </entry>
      <entry>
        <act>
          <code displayName="temp_1:code_3" />
        </act>
      </entry>
    </section>
    <section>
      <templateId value="temp_2" />
      <entry>
        <act>
          <code displayName="temp_2:code_1" />
        </act>
      </entry>
      <entry>
        <act>
          <code displayName="temp_2:code_2" />
        </act>
      </entry>
    </section>
  </component>
</document>

从这个具体的例子中,我只想从templateId值为temp_2的部分获取displayName值。这是我正在使用的XSL代码,但它正在获取所有内容,而不仅仅是我想要的部分。我知道第一个“何时”正在工作,因为正确的标题(在span标记之间)正确显示。这只是通过条目的每个人。

<xsl:tempalte match="/">
<xsl:choose>
  <xsl:when test="//templateId/@value='temp_2'">
    <div style="margin-bottom: 5px; padding: 5px; border-bottom: 1px solid #000000;">
      <span style="font-weight: bold;">Template 2: </span>
      <br />
      <xsl:choose>
        <xsl:when test="count(//section/entry) != 0">
          <xsl:for-each select="//section/entry">
            <xsl:choose>
              <xsl:when test="position() = 1">
                <xsl:value-of select="act/code/@displayName" />
              </xsl:when>
              <xsl:otherwise>
                <br/>
                <xsl:value-of select="act/code/@displayName" />
              </xsl:otherwise>
            </xsl:choose>
          </xsl:for-each>
        </xsl:when>
        <xsl:otherwise>
          No codes to display
        </xsl:otherwise>
      </xsl:choose>
    </div>
  </xsl:when>
</xsl:choose>
</xsl:template>

它应该显示如下:

temp_2:code_1
<br>temp_2:code_2

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

我想你想彻底重新学习XSLT及其理念。不要像它是BASIC那样编程。至少在您的情况下,基本模式是XSLT程序是处理匹配元素的模板集合。不要使用ifchoose乱丢代码,而是使用适当的匹配条件编写模板。而不是BASIC的FOR I=1 TO 10,而是使用<xsl:apply-templates/>来“迭代”孩子们。这是基本的想法:

<xsl:template match="/">
    <html>
        <xsl:apply-templates/>
    </html>
</xsl:template>

<xsl:template match="templateId"/> <!-- skip templateID elements by default -->

<xsl:template match="templateId[@value='temp_2']">
    <div style="margin-bottom: 5px; padding: 5px; border-bottom: 1px solid #000000;">          
        <span style="font-weight: bold;">Template 2: </span>
        <xsl:apply-templates/>
    </div>
</xsl:template>

<xsl:template match="code">
    <xsl:value-of select="@displayName"/>
    <xsl:if test="position() != 1"><br/></xsl:if>
</xsl:template>

<xsl:template match="section[count(entry)=0]">
    No codes to display
</xsl:template>

为什么没有act元素的模板?好吧,默认情况下,XSLT会为您提供一个<xsl:apply-templates/>

的模板

答案 1 :(得分:0)

根据您的描述,听起来您只需要在for-each中使用temp_2值。

在这种情况下,您可以将您的选择更新为以下内容:

<xsl:for-each select="//section[templateId/@value = 'temp_2']/entry">

这样可以抓取entrysectiontemplateIdvalue的{​​{1}}属性{{1}}等于'temp_2'。

相关问题