如何在搜索替换场景中使用XSLT?

时间:2010-12-18 13:24:22

标签: xml xslt

我有一个XML文件,在某些位置有某些值。我希望能够在这些位置替换/添加/删除值。

以下是:

  1. 所有位置仅引用属性节点。
  2. 如果某个位置引用了非现有属性节点,则必须存在所有者元素节点。
  3. 在编写XSL文件时已知新值。
  4. 鉴于这些条件,我已经实现了一个临时解决方案,它接受XAML文件中的键值列表,其中键是XPATH,值是,值,并且完全符合我的需要,只是为了实现,我当已经有法拉利 - XSL转换时发明了一个轮子。

    我的问题是这个。给定一个XML,什么是XSL,在XML上应用哪个:

    1. /a/b/@c的值替换为另一个值,例如D。如果某些/a/b元素没有c属性,则应将其添加。
    2. 删除属性/a/d/@e(如果存在)。别无其他。
    3. 感谢。

2 个答案:

答案 0 :(得分:3)

XSLT 1.0:

<!-- the identity template copies everything not matched elsewhere -->
<xsl:template match="node()|@*">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*" />
  </xsl:copy>
</xsl:template>

<!-- special handling for /a/b elements -->
<xsl:template match="/a/b">
  <!-- copy the element itself -->
  <xsl:copy>
    <!-- handle all attributes -->
    <xsl:apply-templates select="@*" />
    <!-- create (or overwrite!) an attribute named "c" -->
    <xsl:attribute name="c">
      <xsl:value-of select="'D'" />
    </xsl:attribute>
    <!-- handle all other child nodes -->
    <xsl:apply-templates select="node()" />
  </xsl:copy>
</xsl:template>

<!-- empty template to delete /a/d/@e -->
<xsl:template match="/a/d/@e" />

答案 1 :(得分:-2)

我建议您在这里略微错误地概念化XSL。听起来好像你在程序上想象它,即“我如何表达'做X到Y'”,而不是“从结构X到结构Y的映射是什么”,这正是XSL的真正含义。

你会想要这样的东西:

<xsl:for-each select="//a">
    <xsl:copy>
        <xsl:for-each select="b">
            <xsl:copy>
                <xsl:attribute name="c">
                    <xsl:value-of select="$D"/> 
                </xsl:attribute> 
            </xsl:copy>
        </xsl:for-each
    </xsl:copy>
</xsl:for-each>

(n.b。“$ D”语法表示一个变量取消引用,即'插入变量D'的值。我猜这是你想要的,但你可以从任何地方得到D.)

所以,你真的不需要告诉XSL'添加c'或'删除e'。你告诉它应该有什么,否则它什么都不做。