首页 > 解决方案 > xslt - 向所有匹配的 xml 子元素添加属性(不移动它们)

问题描述

在将 XML 导入 InDesign 之前,我使用 XSLT 对其进行转换。

一些元素包括带有许多子元素的文本,这些子元素的格式为斜体、粗体等。为了使斜体在 InDesign 中工作,我想为这些子元素添加一个属性。

不幸的是,到目前为止,在我的尝试中,我无法弄清楚如何将属性添加到所有这些子元素,同时将它们留在父元素中的相同位置。

所以我想采用一些看起来像这样的 XML:

<copy_block>
    A section of text of an unknown length in which might appear <i>one or more</i> sections 
    of italics <i>which I want to add</i> an attribute to.
</copy_block>

并使用我的 XSL 样式表将其转换为:

<copy_block>
    A section of text of an unknown length in which might appear <i cstyle="stylename">one or more</i> sections 
    of italics <i cstyle="stylename">which I want to add</i> an attribute to.
</copy_block>

我认为这不会那么难,但出于某种原因,我很难过。任何帮助将不胜感激。

谢谢!

标签: xmlxslt

解决方案


身份模板开始

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

(在 XSLT 3.0 中,您可以将其替换为 just <xsl:mode on-no-match="shallow-copy"/>

这涉及复制所有元素和节点不变。然后,您需要做的就是添加一个覆盖模板,以匹配i添加一个属性的模板。

<xsl:template match="i">
  <i cstyle="stylename">
    <xsl:apply-templates />
  </i>
</xsl:template>

试试这个完整的 XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes"/>

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

  <xsl:template match="i">
    <i cstyle="stylename">
      <xsl:apply-templates />
    </i>
  </xsl:template>
</xsl:stylesheet>

在http://xsltfiddle.liberty-development.net/nc4NzR2上查看它的实际应用


推荐阅读