copy-of使用搜索和替换相对路径



我想从外部文件中插入一个html片段到我的输出文档中,使用下面描述的copy-of: https://stackoverflow.com/a/5976762/18427492截断的html是一个导航栏,也被其他(python)脚本用来生成其他html文件。我需要替换"href"来匹配我在XSLT变量中的相对路径。

完整文件内容(要复制的模板文件):

<ul class="nav">
<li class="fineprint">MyNiceGame Developer Mode Documentation</li>
<li class="switchlang"><a href="../en/content.html"><img src="/deco/dco_en_sml.gif" alt="English" border="0"></img></a></li>
<li><a href="../../sdk/index.html">Introduction</a></li>
<li><a href="../../content.html">Contents</a></li>
<li><a href="../../search.php">Search</a></li>
<li><a href="../../sdk/console.html">Engine</a></li>
<li><a href="../../sdk/cmdline.html">Command Line</a></li>
<li><a href="../../sdk/files.html">Game Data</a></li>
<li><a href="../../sdk/script/index.html">Script</a></li>
</ul>

那么我如何将这个片段插入到我的XSL文档中并替换../../sdk/(有可能将此字符串更改为{replace-me}/sdk/...之类的东西)与我已经在XSLT变量中拥有的相对路径?

我的XSLT文档(我想用模板文件处理取代<xsl:call-template name="nav"/>):

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="3.0" xpath-default-namespace="https://clonkspot.org" exclude-result-prefixes="xs">
<xsl:output method="html" encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01//EN"
doctype-system="http://www.w3.org/TR/html4/strict.dtd"/>
<xsl:template match="/clonkDoc">
<html>
<body>
<xsl:call-template name="nav"/>
<xsl:apply-templates select="func"/>
<!-- other possible nodes under /clonkDoc -->
<xsl:call-template name="nav"/>
</body>
</html>
</xsl:template>
<xsl:template name="nav">
<xsl:param name="relpath" tunnel="yes"/>
<ul class="nav">
<li class="fineprint">
<xsl:when test='lang("en")'>>MyNiceGame Developer Mode Documentation</xsl:when>
</li>
<!-- Other li elements -->
</xsl:template>

示例源文件:

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<clonkDoc xmlns="https://clonkspot.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://clonkspot.org ../../../clonk.xsd" xml:lang="de">
<func>
<!-- other nodes -->
</func>
</clonkDoc>

目标文件:

<!DOCTYPE html
PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<!-- stuff -->
</head>
<body>
<ul class="nav">
<!-- The corrected li elements with modified a href link -->
</ul>
<!-- Other stuff from source file (<func>) -->
<ul class="nav">
<!-- The corrected li elements with modified a href link -->
</ul>
</body>
</html>

Martin Honnen针对我的xpath-default-namespace具体案例的解决方案:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="3.0" xpath-default-namespace="https://clonkspot.org" exclude-result-prefixes="xs">
<xsl:output method="html" encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01//EN"
doctype-system="http://www.w3.org/TR/html4/strict.dtd"/>
<xsl:template match="/clonkDoc">
<html>
<body>
<xsl:apply-templates select="doc('file.html')//ul[@class = 'nav']" xpath-default-namespace="" mode="fix-links"/>
<xsl:apply-templates select="func"/>
<!-- other possible nodes under /clonkDoc -->
<xsl:apply-templates select="doc('file.html')//ul[@class = 'nav']" xpath-default-namespace="" mode="fix-links"/>
</body>
</html>
</xsl:template>
<xsl:mode name="fix-links" on-no-match="shallow-copy"/>
<xsl:template mode="fix-links" match="ul/li/a/@href" xpath-default-namespace="">
<xsl:message>Value href: <xsl:value-of select="."></xsl:value-of></xsl:message>
<xsl:attribute name="{name()}" select="replace(., '../../sdk', 'foobar')"/>
</xsl:template>

copy-of做一个深度复制,如果你想转换输入节点(甚至只是他们的属性值)你写模板这样做,例如<xsl:apply-templates select="doc('file.xml')//ul[@class = 'nav']" mode="fix-links"/>,或者,也许,正如编辑说的片段与ul都在文件中,使用<xsl:apply-templates select="doc('file.xml')" mode="fix-links"/>,和

<xsl:mode name="fix-links" on-no-match="shallow-copy"/>
<xsl:template mode="fix-links" match="ul/li/a/@href">
<xsl:attribute name="{name()}" select="replace(., '../../sdk', $varname)"/>
</xsl:template>

xsl:mode声明仅适用于XSLT 3,在较早的版本中声明该模式的恒等转换,例如

<xsl:template mode="fix-links" match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="fix-links"/>
</xsl:copy>
</xsl:template>

XSLT 1中的或

<xsl:template mode="fix-links" match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="#current"/>
</xsl:copy>
</xsl:template>

XSLT中的

XSLT 3示例(稍微调整了一下,以便演示使用主输入)输出

<ul class="nav">
<li class="fineprint">MyNiceGame Developer Mode Documentation</li>
<li class="switchlang"><a href="../de/content.html"><img src="/deco/dco_de_sml.gif" alt="German" border="0"/></a></li>
<li><a href="../sdk2/index.html">Introduction</a></li>
<li><a href="../../content.html">Contents</a></li>
<li><a href="../../search.php">Search</a></li>
<li><a href="../sdk2/console.html">Engine</a></li>
<li><a href="../sdk2/cmdline.html">Command Line</a></li>
<li><a href="../sdk2/files.html">Game Data</a></li>
<li><a href="../sdk2/script/index.html">Script</a></li>
</ul>

对于最新编辑的信息,您要处理的辅助输入文档中没有名称空间中的元素,而您的主输入文档中有XSLT用作xpath-default-namespace的特定名称空间中的元素,在这种情况下,您需要覆盖辅助输入中的任何选择,例如

<xsl:mode name="fix-links" on-no-match="shallow-copy"/>
<xsl:template mode="fix-links" match="ul/li/a/@href" xpath-default-namespace="">
<xsl:attribute name="{name()}" select="replace(., '../../sdk', $varname)"/>
</xsl:template>

,如果你继续使用apply-templates与元素选择器,也有,例如<xsl:apply-templates select="doc('file.xml')//ul[@class = 'nav']" xpath-default-namespace="" mode="fix-links"/>

最新更新