值断开在XSLT模板中输出HTML

时间:2013-07-12 12:06:07

标签: xml xslt

我对XSLT很陌生,我遇到以下问题:

我想有这个输出:

<div class="member">
    <h2><a href="#">The First Firm</a></h2>
    <div class="slidecontent">
        <p>
            Adress:<br>
            The First Firm<br>
            Some Adress 123
        </p>
        <div class="downloadsection">
            Redegørelser og Rapporter/The First Firm/Miljøredegørelse-2011.pdf
        </div>
    </div>
</div>

<div class="member">
    <h2><a href="#">The Second Firm</a></h2>
    <div class="slidecontent">
        <p>
            Adress:<br>
            The Second Firm<br>
            Some Adress 123
        </p>
        <div class="downloadsection"></div>
    </div>
</div>

我的XML看起来像这样(前3行被剥离 - 编辑不喜欢它们):

    <Template>
        <loop name="Rows">
          <item>
             <loop name="Row">
                <item>
                   <Row.ColumnName>FirmName</Row.ColumnName>
                   <Row.Value>The First Firm</Row.Value>
                   <Row.Count>0</Row.Count>
                   <Column.Count>0</Column.Count>
                </item>
                <item>
                   <Row.ColumnName>FirmAdress</Row.ColumnName>
                   <Row.Value>Some Adress 123</Row.Value>
                   <Row.Count>0</Row.Count>
                   <Column.Count>1</Column.Count>
                </item>
                <item>
                   <Row.ColumnName>Miljoredegorelse</Row.ColumnName>
                   <Row.Value>Redegørelser og Rapporter/The First Firm/Miljøredegørelse-2011.pdf</Row.Value>
                   <Row.Count>0</Row.Count>
                   <Column.Count>2</Column.Count>
                </item>
             </loop>
          </item>
          <item>
             <loop name="Row">
                <item>
                   <Row.ColumnName>FirmName</Row.ColumnName>
                   <Row.Value>The Second Firm</Row.Value>
                   <Row.Count>0</Row.Count>
                   <Column.Count>0</Column.Count>
                </item>
                <item>
                   <Row.ColumnName>FirmAdress</Row.ColumnName>
                   <Row.Value>Some Adress 456</Row.Value>
                   <Row.Count>0</Row.Count>
                   <Column.Count>1</Column.Count>
                </item>
                <item>
                   <Row.ColumnName>Miljoredegorelse</Row.ColumnName>
                   <Row.Value></Row.Value>
                   <Row.Count>0</Row.Count>
                   <Column.Count>2</Column.Count>
                </item>
             </loop>
          </item>
       </loop>
    </Template>

和XSLT:

<xsl:param name="numcolumns" select="3" />
<xsl:template match="/">
    <xsl:apply-templates select="Template" />
</xsl:template>
<xsl:template match="Template">
    <xsl:call-template name="MemberList" />
</xsl:template>
<xsl:template name="MemberList">
    <xsl:for-each select="loop[@name='Rows']/item[((position() - 1) mod $numcolumns) = 0]">
            <xsl:for-each select=".|following-sibling::*[position() &lt; $numcolumns]">
                <div class="member">
                    <h2>
                        <a href="#">
                        <xsl:for-each select="loop[@name='Row']/item">
                            <xsl:if test="Row.ColumnName='FirmName' and string-length(Row.Value)!='0'">
                                <xsl:apply-templates select="Row.Value" />
                            </xsl:if>
                        </xsl:for-each>
                        </a>
                    </h2>
                    <div class="slidecontent">
                        <p>
                            <xsl:text>Adress: </xsl:text><br />
                            <xsl:for-each select="loop[@name='Row']/item">
                                <xsl:if test="Row.ColumnName='FirmAdress' and string-length(Row.Value)!='0'">
                                    <xsl:apply-templates select="Row.Value" /><br />
                                </xsl:if>
                            </xsl:for-each>
                        </p>

                        <div>
                            <xsl:attribute name="class">
                                <xsl:text>downloadsection</xsl:text>
                            </xsl:attribute>
                            <xsl:for-each select="loop[@name='Row']/item">
                                <xsl:if test="Row.ColumnName='Miljoredegorelse' and string-length(Row.Value)!='0'">
                                    <xsl:apply-templates select="Row.Value" />
                                </xsl:if>
                            </xsl:for-each>
                        </div>
                    </div>
                </div>
            </xsl:for-each>
    </xsl:for-each>
</xsl:template>

当我从第二家公司输出Row.Column“Miljoredegorelse”时输出中断。

Row.Value显示正确 - 但不知何故后</div>没有出来。第一个div <div class="downloadsection">以某种方式自我闭合,看起来像<div class="downloadsection" />

为什么会这样?有人可以帮我理解吗?

1 个答案:

答案 0 :(得分:0)

这对我来说是对的。您的if条件正在测试

Row.ColumnName='Miljoredegorelse' and string-length(Row.Value)!='0'

并且在您发布的第二家公司的Miljoredegorelse示例XML中,Row.Value为空,因此and的右侧失败。因此没有匹配项,没有子节点在div内输出,所以序列化器生成一个空元素。

如果你正在制作HTML输出,那么如果你添加

,你可能会得到更好的结果
<xsl:output method="html" />

到你的样式表。根据处理器的不同,这可能会使<div></div>而不是<div/>用于空元素(两种形式在XML / XHTML中都相同)。


风格点,而不是

<xsl:for-each select="loop[@name='Row']/item">
  <xsl:if test="somecondition">

您可以将if测试合并到for-each选择表达式

<xsl:for-each select="loop[@name='Row']/item[somecondition]">

从技术上讲,这不是100%完全相同,但只有在position()的正文中使用for-each函数时才会出现差异,这是你在这里做的。

如果for-each中唯一的内容是apply-templates,那么您可以更进一步消除for-each

<xsl:apply-templates select="loop[@name='Row']/item[
       Row.ColumnName='Miljoredegorelse' and string-length(Row.Value)!='0'
     ]/Row.Value" />