XSLT:Can I update value in xml node using xslt?

2019-03-29 22:00发布

问题:

For example I have a xml like

 <books>
   <book id="1">
     <title id="11" name="Basic XML"/>
     <price id="12" amount="500"/>
     <quantity id="13" number="10"/>
   </book>
 </books>

Can update the name of the book "Basic XML" to "Basic XSLT" or change any other attributes of any node using XSLT? If yes, can anyone give me some examples on how to do it?

Thanks in advance.

回答1:

This transformation:

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

 <my:reps>
  <repAttr name="name" value="Basic XSLT"/>
  <repAttr name="amount" value="300"/>
  <repAttr name="number" value="20"/>
 </my:reps>

 <xsl:strip-space elements="*"/>

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

 <xsl:template match=
   "@*[name()=document('')/*/my:reps/*/@name]">

   <xsl:attribute name="{name()}">
    <xsl:value-of select=
    "document('')/*/my:reps/*[@name=name(current())]/@value"/>
   </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<books>
    <book id="1">
        <title id="11" name="Basic XML"/>
        <price id="12" amount="500"/>
        <quantity id="13" number="10"/>
    </book>
</books>

produces the wanted, correct result:

<books>
   <book id="1">
      <title id="11" name="Basic XSLT"/>
      <price id="12" amount="300"/>
      <quantity id="13" number="20"/>
   </book>
</books>

Explanation:

  1. The identity rule/template copies every node "as-is".

  2. The identity template is overriden by a single template matching any attribute whose name can be found as value of one of the name attributes of a repAttr element that is specified in the my:reps element (parameters embeded in the XSLT stylesheet).

  3. In this case the attribute is re-created (not copied) with the same name and with the new value, specified in the corresponding repAttr element (its value attribute).



回答2:

I cannot "update" the input Xml as XSLT is purely an output driven technology. It creates anew document and cannot modify the existing one.

You could make an almost identical copy but as @Oded comment points out XSLT may be overkill. The xsl would look something like (a modified identity transform)

<xsl:stylesheet version="1.0">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
   <xsl:template match="title/@Name">
     <!-- insert logic here to change the value as appropriate -->
   </xsl:template>
</xsl:stylesheet>


标签: xml xslt