我在这里多次看到类似的问题,但我不确定它们是否适用于我的案例,或者我只是不理解这个过程。
我有一个XML文件,其中包含一个规则列表:
<rules>
<rule id="1">
<block>
[HTML content]
</block>
<block>
[HTML content]
</block>
<block>
[HTML content]
</block>
</rule>
<rule id="2">
<block>
[HTML content]
</block>
<block>
[HTML content]
</block>
</rule>
[...]
</rules>
现在我的代码是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xsl:template match="/rules/rule">
[some output to create the header and title]
<xsl:for-each select="block">
<xsl:copy-of select="./node()" />
</xsl:for-each>
[some output to create the footer]
</xsl:template>
</xsl:stylesheet>
需要明确的是,这不是整个文档,而是当用户点击规则查看内容时通过AJAX调用的部分,代码被简化了很多,关于如何显示各种block
元素,内部需要做出一些决定,但现在这些部分对我的问题来说是不必要的,只会使阅读代码变得更加困难。
在这种特殊的情况下,XSLT可能看起来并不合适,因为我直接存储HTML内容,但这是一个更大项目的一部分,其中的数据更为示意性,这实际上是我不得不求助于此解决方案的唯一部分。
然而,在rule
标签内,存在使用规则的ID和第二个编号(例如1-1、1-2、…)进行编号的表。。。问题是,我有大约20条规则,并计划以非线性的方式扩展列表。现在我想在规则1和规则2之间添加一个规则,所以我必须更正以下所有表ID。这种情况在过去已经发生过,我相信将来还会发生,所以我想避免这种无用的额外工作,用<id />
标签替换静态数字,例如在Table <id />-12: [...]
中,并用规则的ID替换<id />
。我试图以这种方式修改代码:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xsl:template match="/rules/rule">
[some output to create the header and title]
<xsl:for-each select="block">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:for-each>
[some output to create the footer]
</xsl:template>
<xsl:template match="id"><xsl:value-of select="ancestor::rule/@id" /></xsl:template>
</xsl:stylesheet>
替换是有效的,唯一的问题是<block>
标签没有像以前的代码那样被删除,而其他标签都消失了。我只有一个没有任何HMTL标记的文本块。
我没能想出这个解决方案,我从这类问题中复制了它,但这是我第一次遇到<xsl:copy>
和<xsl:apply-templates>
标签,所以我真的不确定它们是如何工作的。此外,我发现的所有例子都与之前链接的例子相似,需要一个几乎完全相同的副本。我还必须在主输出周围添加很多额外的代码,我不确定这与替换是如何交互的。
编辑:我还尝试了变体
<xsl:apply-templates select="node()|@*">
<xsl:copy-of select="./node()" />
</xsl:apply-templates>
在for-each
循环中,但我得到了相同的结果:文本没有标记,但替换有效。看起来apply-templates
标签删除了所有标签,但我不知道如何让它保留它们。
查看解决方案中的for-each
循环:
<xsl:for-each select="block">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:for-each>
在这个循环中:
<xsl:copy>
输出打开标签,实际上是<block>
<xsl:apply-templates .../>
-"执行"源标记的内容</xsl:copy>
输出结束标记,这次是</block>
由于不需要<block>
标记,只需删除<xsl:copy>
和</xsl:copy>
即可。
为了防止其他标签消失,请将身份模板添加到您的剧本
原因是元素的内置模板:
- 不"复制"打开和关闭标签
- 它只是将模板应用于它们的子级,包括文本节点
您必须覆盖此项,包括标识模板。