所以我的 XML 看起来像:
<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="reports.xsl"?>
<analysis>
<layers>
<layer name="Initial Bool" id="l0">
<code><![CDATA[some
multiline text
goes here]]></code>
</layer>
</layers>
<report name="Some Node">
<issues>
<issue>
<layer id="l0" />
<name>Replace expression</name>
<description>
Test description.
</description>
<locations>
<replace start="20" end="30">hello</replace>
</locations>
</issue>
</issues>
</report>
</analysis>
我当前的 XSLT 是:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="html" />
<xsl:template match="/analysis">
<html>
<head>
<title>Tychaia Analysis Reports</title>
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js">
</script>
</head>
<body>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<xsl:template match="/analysis/layers">
<!-- Do nothing with layers as we reference them from the reports -->
</xsl:template>
<xsl:template match="/analysis/report">
<h2>
<xsl:value-of select="@name" />
</h2>
<xsl:apply-templates />
</xsl:template>
<xsl:template match="/analysis/report/issues">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="/analysis/report/issues/issue">
<h3>
<xsl:value-of select="name" />
</h3>
<p>
<xsl:value-of select="description" />
</p>
<code style="border: none;" class="prettyprint">
<!-- This is the bit that I can't work out how to do (ideally the
replaced content would also then get passed into
remove-leading-whitespace as the text data):
<xsl:call-template name="format-locations">
<xsl:with-param name="text" select="/analysis/layers/layer[@id=current()/layer/@id]" />
<xsl:with-param name="locations" select="locations" />
</xsl:call-template>
-->
<xsl:call-template name="remove-leading-whitespace">
<xsl:with-param name="text" select="/analysis/layers/layer[@id=current()/layer/@id]" />
</xsl:call-template>
</code>
</xsl:template>
<!-- THIS DOESN'T WORK -->
<xsl:template name="format-locations">
<xsl:param name="text" />
<xsl:param name="locations" />
<xsl:variable name="result" select="$text" />
<xsl:for-each select="$locations/replace">
<xsl:variable name="result">
<xsl:value-of select="substring($result, 1, current()/@start)" />
<xsl:text>yo replaced</xsl:text>
<xsl:value-of select="substring($result, current()/@end)" />
</xsl:variable>
</xsl:for-each>
<xsl:copy-of select="$result" />
</xsl:template>
<!-- Removes leading whitespaces for code rendering -->
<xsl:template name="remove-leading-whitespace">
<xsl:param name="text" />
<xsl:choose>
<xsl:when test="substring($text, 1, 1) = ' ' or substring($text, 1, 1) = '
' or substring($text, 1, 1) = ' '">
<xsl:call-template name="remove-leading-whitespace">
<xsl:with-param name="text" select="substring($text, 2)" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="$text" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Replaces spaces and newlines in code with nbsp and <br/> -->
<xsl:template name="replace-spaces">
<xsl:param name="text" />
<xsl:choose>
<xsl:when test="contains($text, ' ')">
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-before($text, ' ')" />
</xsl:call-template>
<xsl:text> </xsl:text>
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-after($text, ' ')" />
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($text, '
')">
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-before($text, '
')" />
</xsl:call-template>
<br />
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-after($text, '
')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
我希望能够<code>
根据<locations>
. 这样报告就可以突出显示代码的部分内容以及每个部分的消息。
但是,我当前的策略format-locations
不起作用,因为您不能在 XSLT 中第二次设置变量,但我需要以<location>
非递归方式循环内部的子级,即嵌套替换标签没有意义彼此喜欢<replace ...><replace ...>...</replace></replace>
只是因为 XSLT 不会递归地迭代兄弟姐妹。
无论如何我可以让这个 XSLT 遍历兄弟姐妹并根据需要执行替换吗?