What XSLT will copy my XML document, modifying elements at a certain path by changing one attribute value and deleting another attribute, and get past the error message I am encountering?
My XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no" encoding="UTF-8" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/document/body/table/cell[@a2='delete me'][@a3='change me']" >
<!-- Not trying to change @a3 yet, just delete @a2. -->
<xsl:copy-of select="@*[name(.)!='a2']|node()" />
</xsl:template>
</xsl:stylesheet>
My input XML document (simplified from a real LibreOffice document example):
<?xml version="1.0" encoding="UTF-8"?>
<document>
<body>
<otherstuff/>
<table>
<cell id="1" a1="keep me" a2="delete me" a3="change me">
cell contents #1
</cell>
<cell id="2" a1="keep me too">
cell contents #2
</cell>
<not_cell id="3" a1="keep me" a2="delete me" a3="change me">
not_cell contents #3
</not_cell>
</table>
<otherstuff/>
</body>
</document>
What I want to change is that cell
elements with attributes a2="delete me"
and a3="change me"
should change. I want to delete the attribute a2
, and change the value of a3
so that a3="changed"
. All the rest of the cell
element is unchanged. All other parts of the XML document are unchanged.
Expected output document: same as input, except for <cell id='1' …/>
:
<cell id="1" a1="keep me" a3="changed">
Note that <not_cell id="3" a2="delete me" …/>
is not touched, because it is not a cell
element.
What I get when I apply this XSLT to this document:
% xsltproc Error-Cannot-add-an-attribute-node.xslt Doc.xml
runtime error: file Error-Cannot-add-an-attribute-node.xslt line 49 element copy-of
Cannot add an attribute node to a non-element node.
This seems to say that the copy-of
expression is attempting to apply an attribute to an attribute or to element text. I can't follow the execution of XSLT well enough to understand where exactly it goes wrong. Can you explain that?
What is the right XSLT pattern (preferably XSLT-1.0) for making this transformation?
(It may be that the answer, XSLT: How to change an attribute value during xsl:copy?, will lead me to the right XSLT pattern, but I can't quite see it. And, it doesn't address why the XSLT I am trying leads to that error message.)