XSLT:如果另一个属性匹配,则更改属性值

时间:2014-11-26 19:15:11

标签: xml xslt

请帮忙,我是XSLT的新手,所以我很抱歉这些愚蠢的问题。

当/ Actor / Relative / Place / @ adj = / Actor / Context /时,我需要一种方法将数据从相应的/ Actor / Context / ID / card / @ val复制到/ Actor / Relative / SecPlace / @ val ID / @帐户

我想出了这个脚本,但它只改变了/ Actor / Relative / Place / @ adj的值,而不是@val。非常感谢您的帮助。

XML:

<Actor>
    <Relative>
        <Place adj="12345"/>
        <SecPlace zok="abc"/>
    </Relative>
    <Context>
        <ID account="54321">
            <Card val="abb"/>
        </ID>
        <ID account="12345">
            <Card val="def"/>
       </ID>
    </Context>
</Actor>

XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:param name="id-to-change" select="/Actor/Context/ID/@account"/>
<xsl:param name="new-name" select="/Actor/Context/ID/Card/"/>

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

<xsl:template match="@adj">
  <xsl:choose>
     <xsl:when test=". = $id-to-change">
        <xsl:attribute name="adj">
           <xsl:value-of select="$new-name"/>
        </xsl:attribute>
     </xsl:when>
     <xsl:otherwise>
        <xsl:copy />
     </xsl:otherwise>
   </xsl:choose>
</xsl:template>

</xsl:stylesheet>

1 个答案:

答案 0 :(得分:1)

考虑使用密钥按ID属性

查找account元素
<xsl:key name="Context" match="Context/ID" use="@account" />

您说要将属性复制到SecPlace元素,在这种情况下,您应该有一个与SecPlace匹配的模板,但是您可以添加条件以仅匹配关联的Place {1}}元素具有匹配的Context/ID(使用密钥检查)

<xsl:template match="Relative[key('Context', Place/@adj)]/SecPlace">

然后,您可以使用该键复制该属性

<xsl:copy-of select="key('Context', ../Place/@adj)/Card/@val" />

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:key name="Context" match="Context/ID" use="@account"/>

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

    <xsl:template match="Relative[key('Context', Place/@adj)]/SecPlace">
        <xsl:copy>
            <xsl:copy-of select="key('Context', ../Place/@adj)/Card/@val"/>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

这不是一个愚蠢的问题。实际上,通过在XSLT中使用身份模板,您已经有了一个良好的开端。

编辑:在回答您的评论时,如果您确实要替换zok属性的值,请更改第二个模板以匹配此属性(而不是匹配父SecPlace元素,并且然后使用更新后的值

替换新属性
<xsl:template match="Relative[key('Context', Place/@adj)]/SecPlace/@zok">
    <xsl:attribute name="zok">
        <xsl:value-of select="key('Context', ../../Place/@adj)/Card/@val"/>
    </xsl:attribute>
</xsl:template>