尝试使用我的xsl

时间:2018-03-27 09:25:03

标签: xml xslt

这是我的xml示例:

https://pastebin.com/Y2NrKhET

(这是w3school为我的案例重新格式化的一个例子)

我的xsl尝试:

<?xml version="1.0" encoding="US-ASCII" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
  <xsl:output method="html" omit-xml-declaration="no" indent="yes" />

<xsl:template match="/">
  <xsl:call-template name="loop">
    <xsl:with-param name="var">3</xsl:with-param>
  </xsl:call-template>
</xsl:template>

<xsl:template name="loop">
  <xsl:param name="var"></xsl:param>
  <xsl:choose>
    <xsl:when test="$var &gt; 0">
     <table border="1">
      <tr bgcolor="#9acd32">
        <th>Index</th>
        <th>TestText</th>
      </tr>

      <td><xsl:value-of select="number($var)"/></td>    

      <xsl:variable name="titleVar" select="concat('catalog/title',string(number($var)))" />
      <td><xsl:value-of select="*[$titleVar]"/></td>

      <!--<td><xsl:text>I am in a loop </xsl:text></td>-->

      <xsl:call-template name="loop">
        <xsl:with-param name="var">
        <xsl:number value="number($var)-1" />
        </xsl:with-param>
      </xsl:call-template>
    </xsl:when>

    <xsl:otherwise>
      <xsl:text>I am out of the loop</xsl:text>
    </xsl:otherwise>


</table>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

我试图循环低谷并获得标题,但我没有得到具体的属性......我得到了所有的目录: - /

如果有人可以帮助我? THX

1 个答案:

答案 0 :(得分:1)

您的样式表格式不正确。您必须在<table>内关闭<xsl:when>

此外,您的模板调用没有多大意义。请注意,xsl:call-template不会更改您当前的节点。您当前的节点将保留为文档节点(不是<catalog>而是整个文档)。因此,在您的情况下,<xsl:template match="/">与您的文档节点匹配,然后调用模板<xsl:template name="loop">,由于您的参数var,该模板会重复3次。请注意,<xsl:apply-templates>也会在您在select属性中定义的任何序列上循环。因此,如果您想循环浏览某些内容,大多数情况下,apply-templates是更好的选择。

您获取所有目录文本节点(实际上并未获得所有目录)的原因是由于以下行:<td><xsl:value-of select="*[$titleVar]"/></td>

<xsl:value-of>以文本形式返回所选节点的值。在您的情况下,这意味着文档中的所有文本节点。这是因为被调用模板循环的上下文因为$titleVar返回一个字符串,所以你的谓词(['catalog/title3'])是没用的。

如果您希望匹配文档中的某个文本节点,并且上下文仍然是文档节点,则可以使用<xsl:value-of select="descendant::node()[parent::title3]"/>之类的模式。请注意,文本节点不是元素节点,因此您必须使用*而不是node()

修改

如果你想处理每个节点,名称以'title'开头,你可以使用像这样的apply-templates(这些是xslt基础知识):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <titles>
            <!-- select a sequence of all child nodes of your
            root element and search for matching templates-->
            <xsl:apply-templates select="catalog/*"/>
        </titles>
    </xsl:template>

    <!-- match every node, which starts with 'title'-->
    <xsl:template match="*[starts-with(name(), 'title')]">
        <title>
            <xsl:value-of select="."/>
        </title>
    </xsl:template>

    <!--match every node, but since the first template is more specific,
    elements starting with 'title' will not be processed-->
    <xsl:template match="*"/>

</xsl:stylesheet>