我对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() < $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" />
。
为什么会这样?有人可以帮我理解吗?
答案 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" />