したがって、次のような 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 で変数を 2 回設定することはできないため、私の現在の戦略は機能しませんが<location>
、非再帰的に内部の子をループする必要があります。単純に、XSLT が兄弟を再帰的<replace ...><replace ...>...</replace></replace>
に反復しないためです。
とにかく、この XSLT で兄弟を反復処理し、必要に応じて置換を実行することはできますか?