XML XSLT -> HTML 转换 - 如何使用 xslt 将 xml 元素文本拆分为点
XML XSLT -> HTML Transformation - How to split xml element text into dot points with xslt
我有一个 XML 数据结构,我正在使用 XSLT 将其转换为 HTML。我需要使用 XSLT 和输出将 XML 的 current_teaching 元素中的文本拆分为点(元素内容中的分号表示我希望拆分发生的位置)。
到目前为止,这就是我所拥有的。
XML/XSLT 文件:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="StaffList.xslt"?>
<StaffList>
<StaffMember>
<title>Dr John Brown</title>
<titledesc>Senior Lecturer, ICU Security Research Institute</titledesc> <!-- example text -->
<telephone>(645) 2545 6988</telephone>
<mobile>04568 6665 666</mobile>
<facsimile>(61 8) 9999 9999</facsimile>
<email>dr.brown@brown.com</email>
<campus>Mountain Range</campus>
<room>18.13</room>
<description>John Brown is a awesome doctor.</description>
<current_teaching>Data Structures; Principles of Distributed Systems; Fundamentals of Software Engineering</current_teaching>
</StaffMember>
</StaffList>
XSLT:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<link rel="stylesheet" type="text/css" href="StaffList.css"/>
</head>
<body>
<xsl:for-each select="StaffList/StaffMember">
<h2 id="title"><xsl:value-of select="title"/></h2>
<h3 id="titledesc"><xsl:value-of select="titledesc"/></h3>
<br></br>
<table>
<tr>
<td id="telephone_1">Telephone</td>
<td id="telephone_2"><xsl:value-of select="telephone"/></td>
</tr>
<tr>
<td id="mobile_1">Mobile</td>
<td id="mobile_2"><xsl:value-of select="mobile"/></td>
</tr>
<tr>
<td id="facsimile_1">Facsimile</td>
<td id="facsimile_2"><xsl:value-of select="facsimile"/></td>
</tr>
<tr>
<td id="email_1">Email</td>
<td id="email_2"><xsl:value-of select="email"/></td>
</tr>
<tr>
<td id="campus_1">Campus</td>
<td id="campus_2"><xsl:value-of select="campus"/></td>
</tr>
<tr>
<td id="room_1">Room</td>
<td id="room_2"><xsl:value-of select="room"/></td>
</tr>
</table>
<br></br>
<br></br>
<p><xsl:value-of select="description"/></p>
<br></br>
</xsl:for-each>
</body>
</html>
</xsl:template></xsl:stylesheet>
我进行了一些搜索并且已经找到了一个可能的解决方案,但是我无法让我的 XSLT 使用它。
这是我尝试过的:
<ul>
<xsl:analyze-string select="string()" regex=".*?[\.;]" flags="sm">
<xsl:matching-substring>
<li><xsl:value-of select="."/></li>
</xsl:matching-substring>
<xsl:non-matching-substring>
<li><xsl:value-of select="."/></li>
</xsl:non-matching-substring>
</xsl:analyze-string>
</ul>
这是在上面的 XSLT 代码的最后一个 br /br 和 /xsl:for-each 之间添加的。
在 XSLT 1.0(这是 Microsoft 处理器将支持的所有内容)中,您需要调用命名模板来递归处理输入。调用看起来像:
<ul>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="current_teaching"/>
</xsl:call-template>
</ul>
和命名模板:
<xsl:template name="tokenize">
<xsl:param name="text"/>
<xsl:param name="delimiter" select="'; '"/>
<xsl:choose>
<xsl:when test="contains($text, $delimiter)">
<li>
<xsl:value-of select="substring-before($text, $delimiter)"/>
</li>
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<li>
<xsl:value-of select="$text"/>
</li>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
XSLT 1.0 标记化模板可以非常简短,证明可以避免 <xsl:choose>
、<xsl:when>
和 <xsl:otherwise>
:
<xsl:template match="current_teaching/text()[normalize-space()]" name="split">
<xsl:param name="pText" select="."/>
<xsl:if test="normalize-space($pText)">
<li><xsl:value-of select="substring-before(concat($pText, ';'), ';')"/></li>
<xsl:call-template name="split">
<xsl:with-param name="pText" select="substring-after($pText, ';')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
它通常会被选中执行,使用代码中的 <xsl:apply-templates>
指令,就像这样:
<ul>
<xsl:apply-templates select="current_teaching"/>
</ul>
说明:
有助于消除此解决方案的复杂性的是使用 Sentinel Programming 的原则。
一个前哨字符 (;
) 附加到字符串,这样就无需分析两种不同的情况——当文本包含分隔符时,当文本不包含分隔符时。
我有一个 XML 数据结构,我正在使用 XSLT 将其转换为 HTML。我需要使用 XSLT 和输出将 XML 的 current_teaching 元素中的文本拆分为点(元素内容中的分号表示我希望拆分发生的位置)。
到目前为止,这就是我所拥有的。
XML/XSLT 文件:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="StaffList.xslt"?>
<StaffList>
<StaffMember>
<title>Dr John Brown</title>
<titledesc>Senior Lecturer, ICU Security Research Institute</titledesc> <!-- example text -->
<telephone>(645) 2545 6988</telephone>
<mobile>04568 6665 666</mobile>
<facsimile>(61 8) 9999 9999</facsimile>
<email>dr.brown@brown.com</email>
<campus>Mountain Range</campus>
<room>18.13</room>
<description>John Brown is a awesome doctor.</description>
<current_teaching>Data Structures; Principles of Distributed Systems; Fundamentals of Software Engineering</current_teaching>
</StaffMember>
</StaffList>
XSLT:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<link rel="stylesheet" type="text/css" href="StaffList.css"/>
</head>
<body>
<xsl:for-each select="StaffList/StaffMember">
<h2 id="title"><xsl:value-of select="title"/></h2>
<h3 id="titledesc"><xsl:value-of select="titledesc"/></h3>
<br></br>
<table>
<tr>
<td id="telephone_1">Telephone</td>
<td id="telephone_2"><xsl:value-of select="telephone"/></td>
</tr>
<tr>
<td id="mobile_1">Mobile</td>
<td id="mobile_2"><xsl:value-of select="mobile"/></td>
</tr>
<tr>
<td id="facsimile_1">Facsimile</td>
<td id="facsimile_2"><xsl:value-of select="facsimile"/></td>
</tr>
<tr>
<td id="email_1">Email</td>
<td id="email_2"><xsl:value-of select="email"/></td>
</tr>
<tr>
<td id="campus_1">Campus</td>
<td id="campus_2"><xsl:value-of select="campus"/></td>
</tr>
<tr>
<td id="room_1">Room</td>
<td id="room_2"><xsl:value-of select="room"/></td>
</tr>
</table>
<br></br>
<br></br>
<p><xsl:value-of select="description"/></p>
<br></br>
</xsl:for-each>
</body>
</html>
</xsl:template></xsl:stylesheet>
我进行了一些搜索并且已经找到了一个可能的解决方案,但是我无法让我的 XSLT 使用它。 这是我尝试过的:
<ul>
<xsl:analyze-string select="string()" regex=".*?[\.;]" flags="sm">
<xsl:matching-substring>
<li><xsl:value-of select="."/></li>
</xsl:matching-substring>
<xsl:non-matching-substring>
<li><xsl:value-of select="."/></li>
</xsl:non-matching-substring>
</xsl:analyze-string>
</ul>
这是在上面的 XSLT 代码的最后一个 br /br 和 /xsl:for-each 之间添加的。
在 XSLT 1.0(这是 Microsoft 处理器将支持的所有内容)中,您需要调用命名模板来递归处理输入。调用看起来像:
<ul>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="current_teaching"/>
</xsl:call-template>
</ul>
和命名模板:
<xsl:template name="tokenize">
<xsl:param name="text"/>
<xsl:param name="delimiter" select="'; '"/>
<xsl:choose>
<xsl:when test="contains($text, $delimiter)">
<li>
<xsl:value-of select="substring-before($text, $delimiter)"/>
</li>
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<li>
<xsl:value-of select="$text"/>
</li>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
XSLT 1.0 标记化模板可以非常简短,证明可以避免 <xsl:choose>
、<xsl:when>
和 <xsl:otherwise>
:
<xsl:template match="current_teaching/text()[normalize-space()]" name="split">
<xsl:param name="pText" select="."/>
<xsl:if test="normalize-space($pText)">
<li><xsl:value-of select="substring-before(concat($pText, ';'), ';')"/></li>
<xsl:call-template name="split">
<xsl:with-param name="pText" select="substring-after($pText, ';')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
它通常会被选中执行,使用代码中的 <xsl:apply-templates>
指令,就像这样:
<ul>
<xsl:apply-templates select="current_teaching"/>
</ul>
说明:
有助于消除此解决方案的复杂性的是使用 Sentinel Programming 的原则。
一个前哨字符 (;
) 附加到字符串,这样就无需分析两种不同的情况——当文本包含分隔符时,当文本不包含分隔符时。