使用XSLT替换带有文本节点的XML标记

问题描述:

我已经在此处看到过类似的问题,但我不确定它们是否适用于我的案例,或者我是否仅仅不理解该过程。使用XSLT替换带有文本节点的XML标记

我有一个包含一系列规则的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元素需要做一些决策,但现在这些部分对于m不是必需的这个问题只会让阅读代码更加困难。

在这种特殊情况下,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标签的文本块。

我无法想出这个解决方案,我复制它的问题,如this one,但这是我第一次遇到<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>

为防止其他标签消失,请将标识模板添加到您的 脚本中。

的原因是,元素内置的模板:

  • 没有“复制”开始和结束标记,
  • 它只采用模板自己的孩子,包括文本节点。

你必须重写这个,包括身份模板

+0

谢谢,它现在有效。我不知道身份模板是什么,我从链接问题中的代码中删除了它。 – GRB