Is there a simple way to copy an element and its attributes while replacing just a few of the attributes?

StackOverflow https://stackoverflow.com/questions/22374514

  •  14-06-2023
  •  | 
  •  

Pergunta

I am using XSLT to copy a file and I want to copy all the attributes of a certain node but I'd like replace some of the attributes with new ones. For example, I might have this:

<Library>
    <Book author="someone" pub-date="atime" color="black" pages="900">
    </Book>
</Library>

How could I copy this but replace pub-date and color with new values? Is there something similar to this?

<xsl:template match="/Library/Book">
    <xsl:copy>
        <xsl:attribute name="pub-date">1-1-1976</xsl:attribute>
        <xsl:attribute name="color">blue</xsl:attribute>
        <xsl:apply-templates select="*@[not pub-date or color] | node()"/>
    </xsl:copy>
</xsl:template>

But this isn't valid of course...

Foi útil?

Solução

Another way is to rely on the fact that if the same attribute is written twice, the last one wins. So:

<xsl:template match="/Library/Book">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:attribute name="pub-date">1-1-1976</xsl:attribute>
        <xsl:attribute name="color">blue</xsl:attribute>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

(Are you quite sure you want to be using the ambiguous date format 1-1-1976?)

Outras dicas

I would start as usual with the identity transformation template

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

and then add

<xsl:template match="Book/@pub-date">
  <xsl:attribute name="pub-date">1-1-1976</xsl:attribute>
</xsl:template>

<xsl:template match="Book/@color">
  <xsl:attribute name="color">blue</xsl:attribute>
</xsl:template>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top