Xml 如何在XSLT的前一个同级中测试多个条件
我有从传统LotusNotes应用程序中提取的XML数据,并嵌入了richtext格式。我试图根据前一个同级中出现的属性格式化每个文本块。我从@Jayvee获得了XSLT的灵感,但它不起作用 这是XML:Xml 如何在XSLT的前一个同级中测试多个条件,xml,xslt,lotus-notes,Xml,Xslt,Lotus Notes,我有从传统LotusNotes应用程序中提取的XML数据,并嵌入了richtext格式。我试图根据前一个同级中出现的属性格式化每个文本块。我从@Jayvee获得了XSLT的灵感,但它不起作用 这是XML: <?xml version="1.0" encoding="UTF-8"?> <document> <item name="Unordered list"> <richtext> <parde
<?xml version="1.0" encoding="UTF-8"?>
<document>
<item name="Unordered list">
<richtext>
<pardef/>
<par def="20">
<run>This is the first </run><run>paragraph of the preamble.</run>
</par>
<par>
<run>This is the second paragraph of the </run><run>preamble.</run>
</par>
<pardef id="21" list="unordered"/>
<par def="21">
<run>This is the </run><run>first bullet.</run>
</par>
<par>
<run>This is the second </run><run>bullet.</run>
</par>
<par def="20">
<run>This is the first </run><run>paragraph of the conclusion.</run>
</par>
<par>
<run>This is the second paragraph of the </run><run>conclusion.</run>
</par>
</richtext>
</item>
<item name="Ordered list">
<richtext>
<pardef/>
<par def="20">
<run>This is the first </run><run>paragraph of the preamble.</run>
</par>
<par>
<run>This is the second paragraph of the </run><run>preamble.</run>
</par>
<pardef id="46" list="ordered"/>
<par def="46">
<run>This is the </run><run>first numbered item.</run>
</par>
<par>
<run>This is the another </run><run>numbered item.</run>
</par>
<par def="20">
<run>This is the first </run><run>paragraph of the conclusion.</run>
</par>
<par>
<run>This is the second paragraph of the </run><run>conclusion.</run>
</par>
</richtext>
</item>
</document>
这是序言的第一段。
这是序言的第二段。
这是第一颗子弹。
这是第二颗子弹。
这是结论的第一段。
这是结论的第二段。
这是序言的第一段。
这是序言的第二段。
这是第一个编号的项目。
这是另一个编号的项目。
这是结论的第一段。
这是结论的第二段。
这是所需的输出:
<html>
<body>
<table border="1">
<tr>
<td>Unordered list</td>
<td>
<p>This is the first paragraph of the preamble.</p>
<p>This is the second paragraph of the preamble.</p>
<ul>
<li>This is the first bullet.</li>
<li>This is the second bullet.</li>
</ul>
<p>This is the first paragraph of the conclusion.</p>
<p>This is the second paragraph of the conclusion.</p>
</td>
</tr>
<tr>
<td>Ordered list</td>
<td>
<p>This is the first paragraph of the preamble.</p>
<p>This is the second paragraph of the preamble.</p>
<ol>
<li>This is the first numbered item.</li>
<li>This is the another numbered item.</li>
</ol>
<p>This is the first paragraph of the conclusion.</p>
<p>This is the second paragraph of the conclusion.</p>
</td>
</tr>
</table>
</body>
无序列表
这是序言的第一段
这是序言的第二段
- 这是第一颗子弹
- 这是第二颗子弹
这是结论的第一段
这是结论的第二段
有序列表
这是序言的第一段
这是序言的第二段
这是第一个编号的项目
这是另一个编号的项目
这是结论的第一段
这是结论的第二段
这是XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="/*">
<html>
<body>
<table border="1">
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="item">
<tr>
<td><xsl:value-of select="@name"/></td>
<td>
<xsl:apply-templates/>
</td>
</tr>
</xsl:template>
<xsl:template match="par">
<xsl:choose>
<xsl:when test="preceding-sibling::pardef[@list] = 'unordered' and preceding-sibling::par[@def][1][@def] != preceding-sibling::pardef[@id]"><xsl:text disable-output-escaping="yes"></ul></xsl:text></xsl:when>
<xsl:when test="preceding-sibling::pardef[@list] = 'ordered' and preceding-sibling::par[@def][1][@def] != preceding-sibling::pardef[@id]"><xsl:text disable-output-escaping="yes"></ol></xsl:text></xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="@def=preceding-sibling::pardef[@id] or (not(@def) and preceding-sibling::par[@def][1][@def=preceding-sibling::pardef[@id]])">
<xsl:choose>
<xsl:when test="preceding-sibling::pardef[@list] = 'unordered' and preceding-sibling::par[@def][1][@def] = preceding-sibling::pardef[@id]"><xsl:text disable-output-escaping="yes"><ul></xsl:text></xsl:when>
<xsl:when test="preceding-sibling::pardef[@list] = 'ordered' and preceding-sibling::par[@def][1][@def] = preceding-sibling::pardef[@id]"><xsl:text disable-output-escaping="yes"><ol></xsl:text></xsl:when>
</xsl:choose>
<li>
<xsl:for-each select="run">
<xsl:value-of select="text()" separator=""/>
</xsl:for-each>
</li>
</xsl:when>
<xsl:when test="not(@def=preceding-sibling::pardef[@id])">
<p>
<xsl:for-each select="run">
<xsl:value-of select="text()" separator=""/>
</xsl:for-each>
</p>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
/保险商实验室
/ol
保险商实验室
ol
上一个问题中的方法使用禁用输出转义
来输出开始和结束标记,这不是一种理想的方法
相反,考虑使用一个键将第一个前面的<代码> PAR < /COD>元素组合在一起,代码<>代码> DEF属性
<xsl:key name="pars"
match="par[not(@def)]"
use="generate-id(preceding-sibling::par[@def][1])" />
要确定是否将组包装在ul
或ol
标记中,您可以获得如下列表类型:
<xsl:variable name="listType" select="preceding-sibling::*[1][self::pardef]/@list" />
然后,您可以对此进行测试,以确定是否将组包装在列表标记中
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:key name="pars" match="par[not(@def)]" use="generate-id(preceding-sibling::par[@def][1])" />
<xsl:template match="/*">
<html>
<body>
<table border="1">
<xsl:apply-templates />
</table>
</body>
</html>
</xsl:template>
<xsl:template match="item">
<tr>
<td><xsl:value-of select="@name"/></td>
<td>
<xsl:apply-templates select="richtext/par[@def]" />
</td>
</tr>
</xsl:template>
<xsl:template match="par[@def]">
<xsl:variable name="listType" select="preceding-sibling::*[1][self::pardef]/@list" />
<xsl:variable name="group" select="self::* | key('pars', generate-id())" />
<xsl:choose>
<xsl:when test="$listType = 'unordered'">
<ol>
<xsl:apply-templates select="$group" mode="list"/>
</ol>
</xsl:when>
<xsl:when test="$listType = 'ordered'">
<ul>
<xsl:apply-templates select="$group" mode="list"/>
</ul>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$group" mode="para" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="par" mode="list">
<li>
<xsl:value-of select="run" separator=""/>
</li>
</xsl:template>
<xsl:template match="par" mode="para">
<para>
<xsl:value-of select="run" separator=""/>
</para>
</xsl:template>
</xsl:stylesheet>
上一个问题中的方法使用禁用输出转义
来输出开始和结束标记,这不是一种理想的方法
相反,考虑使用一个键将第一个前面的<代码> PAR < /COD>元素组合在一起,代码<>代码> DEF属性
<xsl:key name="pars"
match="par[not(@def)]"
use="generate-id(preceding-sibling::par[@def][1])" />
要确定是否将组包装在ul
或ol
标记中,您可以获得如下列表类型:
<xsl:variable name="listType" select="preceding-sibling::*[1][self::pardef]/@list" />
然后,您可以对此进行测试,以确定是否将组包装在列表标记中
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:key name="pars" match="par[not(@def)]" use="generate-id(preceding-sibling::par[@def][1])" />
<xsl:template match="/*">
<html>
<body>
<table border="1">
<xsl:apply-templates />
</table>
</body>
</html>
</xsl:template>
<xsl:template match="item">
<tr>
<td><xsl:value-of select="@name"/></td>
<td>
<xsl:apply-templates select="richtext/par[@def]" />
</td>
</tr>
</xsl:template>
<xsl:template match="par[@def]">
<xsl:variable name="listType" select="preceding-sibling::*[1][self::pardef]/@list" />
<xsl:variable name="group" select="self::* | key('pars', generate-id())" />
<xsl:choose>
<xsl:when test="$listType = 'unordered'">
<ol>
<xsl:apply-templates select="$group" mode="list"/>
</ol>
</xsl:when>
<xsl:when test="$listType = 'ordered'">
<ul>
<xsl:apply-templates select="$group" mode="list"/>
</ul>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$group" mode="para" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="par" mode="list">
<li>
<xsl:value-of select="run" separator=""/>
</li>
</xsl:template>
<xsl:template match="par" mode="para">
<para>
<xsl:value-of select="run" separator=""/>
</para>
</xsl:template>
</xsl:stylesheet>
您的解决方案非常优雅,可以使用我提供的XML代码片段。但在我在这里简化的真实XML中,键不起作用,因为大多数段落都有def属性。我需要在清单声明中匹配所有的PAR节点,其中DEF属性与PARDEF的ID属性相匹配。听起来您可能需要问一个新问题;您的解决方案非常优雅,并且可以使用我使用的XML片段