【问题标题】:XSL test if self-closed element is met in for-each loopXSL 测试是否在 for-each 循环中满足自闭元素
【发布时间】:2012-01-19 17:11:25
【问题描述】:

这是 xml 示例:

<a>
    <b>Text</b>
    <b>Text</b>
    <b>Text</b>
    <page/>
    <b>Text</b>
    <b>Text</b>
    <page/>
    <b>Text</b>
    <b>Text</b>
    <b>Text</b>
    <b>Text</b>
</a>

这是我想要实现的html:

<p>Text Text Text</p>
<p>Text Text</p>
<p>Text Text Text Text</p>

我是第一次使用 XSL,请见谅。

现在我正在使用这个循环:

<xsl:for-each select="a/*">
    <p>
    <xsl:value-of select="."/>
    <xsl:if test="UNKNOWN_TEST">
    </p>
    </xsl:if>
</xsl:for-each>

我的问题是,我需要在这里输入什么而不是 UNKNOWN_TEST?或者也许这不是我应该尝试解决的方式?

【问题讨论】:

    标签: xslt if-statement foreach


    【解决方案1】:

    你看不到它是否自闭,你可以测试它是否为空,无论如何它不会工作,因为你的xsl格式不正确。

    可能的(不是很讨人喜欢的)解决方案:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
     <xsl:template match="/">
      <xsl:for-each select="/a/b[name(preceding-sibling::*[1])!='b']">
       <p>
        <xsl:value-of select="text()"/>
        <xsl:variable name="pp" select="generate-id(preceding-sibling::page[1])" />
        <xsl:variable name="fp" select="generate-id(following-sibling::page[1])" />
        <xsl:for-each select="following-sibling::b[generate-id(preceding-sibling::page[1])=$pp and generate-id(following-sibling::page[1])=$fp]">
         <xsl:value-of select="concat(' ',./text())"/>
        </xsl:for-each>
       </p>
      </xsl:for-each>
     </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 是的,我刚刚注意到我用每个 b 元素打开了 p 标签。你能告诉我该怎么做吗?
    • 我不确定你到底想做什么。例如,您可以为前面没有b 的每个b 选择所有连续的bs。或bs 之间没有page...
    • 每个b 都是书中的一行文字。每个&lt;page/&gt; 表示一页结束,下一页开始。所以我想让每个“页面”(&lt;page/&gt;s 之间的bs)都包裹在&lt;p&gt; 中。我希望这能解释一下。对不起我糟糕的英语。
    • 嗯...这有点棘手,我会尝试为您想出一些尴尬的解决方案...我怀疑它是否完美,但这就是我想到的,等等,我'将其编辑为答案。
    • 谢谢你,迈克尔。我会阅读你的答案和@lwburk 的答案,如果我没有任何其他问题,我会接受。现在它对我来说相当复杂......
    【解决方案2】:

    将 XSLT 视为处理文档的文字文本是错误的。它正在研究一种模型,一种表示,其中&lt;page/&gt;&lt;page&gt;&lt;/page&gt; 是等价的。但是,您对之前的答案发表了以下评论:

    每个b 都是书中的一行文字。每个&lt;page/&gt; 表示一个 页面结束,下一个开始。所以我想要每个“页面”(bs 在&lt;page/&gt;s 之间)包裹在&lt;p&gt; 中。我希望这可以解释 一点点。

    以下样式表使用keyb 元素按其前面的page 分组:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
        <xsl:key name="byPage" match="b" 
                 use="generate-id(preceding-sibling::page[1])"/>
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="a">
            <xsl:copy>
                <!-- handle the first group of b's with no preceding page -->
                <p><xsl:apply-templates select="key('byPage', '')"/></p>
                <xsl:apply-templates select="@*|page"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="page">
            <p><xsl:apply-templates select="key('byPage', generate-id())"/></p>
        </xsl:template>
    </xsl:stylesheet>
    

    产生以下输出:

    <a>
       <p>
          <b>Text</b>
          <b>Text</b>
          <b>Text</b>
       </p>
       <p>
          <b>Text</b>
          <b>Text</b>
       </p>
       <p>
          <b>Text</b>
          <b>Text</b>
          <b>Text</b>
          <b>Text</b>
       </p>
    </a>
    

    【讨论】:

      猜你喜欢
      • 2012-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-01
      • 2013-08-07
      • 2020-02-14
      • 1970-01-01
      相关资源
      最近更新 更多