我需要在应用xsl:fo的嵌套列表中使用带连字符的连字符。我有两个匹配的模板,但只有一个被应用。如果我只使用第一个模板,则外部列表会应用模板。如果我只使用第二个模板,嵌套列表将应用模板。我试图在第二个模板中匹配的模式是任何无序列表,列表项作为父项。非常感谢任何有关获得所需输出的帮助。
XML
<ThisNode>
<ul>
<li>Item One</li>
<li>Item Two</li>
<li>Item Three
<ul>
<li>Sub-Item One</li>
<li>Sub-Item Two</li>
</ul>
</li>
<li>Item Four</li>
<li>Item Five</li>
</ul>
</ThisNode>
XSLT
<xsl:template match="ul">
<fo:list-block>
<xsl:for-each select="./li">
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block font-weight="bold">•</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="8pt">
<fo:block><xsl:value-of select="."/></fo:block>
</fo:list-item-body>
</fo:list-item>
</xsl:for-each>
</fo:list-block>
</xsl:template>
<xsl:template match="li//ul">
<fo:list-block start-indent="8pt">
<xsl:for-each select="./li">
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block font-weight="bold">-</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="16pt">
<fo:block><xsl:value-of select="."/></fo:block>
</fo:list-item-body>
</fo:list-item>
</xsl:for-each>
</fo:list-block>
</xsl:template>
<fo:block text-align="left">
<xsl:apply-templates select="./ThisNode"/>
</fo:block>
渴望输出
• Item One
• Item Two
• Item Three
- Sub-Item One
- Sub-Item Two
• Item Four
• Item Five
仅使用第一次模板或同时使用的实际输出
• Item One
• Item Two
• Item ThreeSub-Item OneSub-Item Two
• Item Four
• Item Five
仅使用第二个模板进行实际输出
Item One Item Two Item Three
- Sub-Item One
- Sub-Item Two
Item Four Item Five
答案 0 :(得分:2)
这似乎是call-template
mode
的好地方,可以区分这两种情况。外部模板调用内部模板:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<fo:block text-align="left">
<xsl:apply-templates select="ThisNode"/>
</fo:block>
</xsl:template>
<xsl:template match="ul">
<fo:list-block>
<xsl:for-each select="li">
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block font-weight="bold">•</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="8pt">
<fo:block>
<!-- I'm not quite sure what you want here -->
<xsl:value-of select="text()"/>
<xsl:apply-templates select="ul" mode="inner"/>
</fo:block>
</fo:list-item-body>
</fo:list-item>
</xsl:for-each>
</fo:list-block>
</xsl:template>
<xsl:template match="ul" mode="inner">
<fo:list-block start-indent="8pt">
<xsl:for-each select="./li">
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block font-weight="bold">-</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="16pt">
<fo:block>
<xsl:value-of select="."/>
</fo:block>
</fo:list-item-body>
</fo:list-item>
</xsl:for-each>
</fo:list-block>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:2)
以下样式表说明了可能的解决方案。您的方法并不遥远 - 但是,它无法解释XSLT处理器的行为。这个表达式:
<xsl:value-of select="."/>
默认返回作为上下文节点的子节点的任何文本节点。但在您的情况下(li
元素的模板匹配),所有后代文本节点都会输出,而不仅仅是li
的直接子节点。
因此,下面的样式表使用
<xsl:value-of select="child::text()"/>
检索li
元素的文本内容,然后<xsl:apply-templates>
处理作为其子项的任何li
元素。
正如你的标题所述,
xsl:fo模板匹配未在嵌套列表中触发
您正确诊断了它。这是因为 - 一旦在模板中匹配li
- 您就不会让XSLT处理器处理后代li
元素。
<强>样式表强>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/ThisNode">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="simple"
page-height="29.7cm"
page-width="21cm"
margin-top="1cm"
margin-bottom="2cm"
margin-left="2.5cm"
margin-right="2.5cm">
<fo:region-body margin-top="3cm"/>
<fo:region-before extent="3cm"/>
<fo:region-after extent="1.5cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="simple">
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="ul[parent::ThisNode]">
<fo:list-block>
<xsl:apply-templates/>
</fo:list-block>
</xsl:template>
<xsl:template match="ul[parent::li]">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="li">
<fo:list-item>
<xsl:choose>
<xsl:when test="parent::ul/parent::ThisNode">
<fo:list-item-label start-indent="1cm">
<fo:block font-weight="bold">•</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="1.5cm">
<fo:block><xsl:value-of select="child::text()"/></fo:block>
</fo:list-item-body>
</xsl:when>
<xsl:otherwise>
<fo:list-item-label start-indent="3cm">
<fo:block font-weight="bold">-</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="3.5cm">
<fo:block><xsl:value-of select="."/></fo:block>
</fo:list-item-body>
</xsl:otherwise>
</xsl:choose>
</fo:list-item>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
输出(XSL-FO)
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="simple" page-height="29.7cm" page-width="21cm" margin-top="1cm"
margin-bottom="2cm"
margin-left="2.5cm"
margin-right="2.5cm">
<fo:region-body margin-top="3cm"/>
<fo:region-before extent="3cm"/>
<fo:region-after extent="1.5cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="simple">
<fo:flow flow-name="xsl-region-body">
<fo:list-block>
<fo:list-item>
<fo:list-item-label start-indent="1cm">
<fo:block font-weight="bold">•</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="1.5cm">
<fo:block>Item One</fo:block>
</fo:list-item-body>
</fo:list-item>Item One
<fo:list-item>
<fo:list-item-label start-indent="1cm">
<fo:block font-weight="bold">•</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="1.5cm">
<fo:block>Item Two</fo:block>
</fo:list-item-body>
</fo:list-item>Item Two
<fo:list-item>
<fo:list-item-label start-indent="1cm">
<fo:block font-weight="bold">•</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="1.5cm">
<fo:block>Item Three
</fo:block>
</fo:list-item-body>
</fo:list-item>Item Three
<fo:list-item>
<fo:list-item-label start-indent="3cm">
<fo:block font-weight="bold">-</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="3.5cm">
<fo:block>Sub-Item One</fo:block>
</fo:list-item-body>
</fo:list-item>Sub-Item One
<fo:list-item>
<fo:list-item-label start-indent="3cm">
<fo:block font-weight="bold">-</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="3.5cm">
<fo:block>Sub-Item Two</fo:block>
</fo:list-item-body>
</fo:list-item>Sub-Item Two
<fo:list-item>
<fo:list-item-label start-indent="1cm">
<fo:block font-weight="bold">•</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="1.5cm">
<fo:block>Item Four</fo:block>
</fo:list-item-body>
</fo:list-item>Item Four
<fo:list-item>
<fo:list-item-label start-indent="1cm">
<fo:block font-weight="bold">•</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="1.5cm">
<fo:block>Item Five</fo:block>
</fo:list-item-body>
</fo:list-item>Item Five
</fo:list-block>
</fo:flow>
</fo:page-sequence>
</fo:root>
输出(PDF)