XSLT: How to change the parent tag name and Delete an attribute from XML file?
I have an XML file from which I need to delete an attribute with name "Id" (It must be deleted wherever it appears) and also I need to rename the parent tag, while keeping its attributes and child elements unaltered .. Can you please help me modifying the code. At a time, am able to achieve only one of the two requirements .. I mean I can delete that attribute completely from the document or I can change the parent tag .. Here is my code to which removes attribute "Id":
<xsl:template match="@*|n开发者_如何学Pythonode()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@Id[parent::*]">
</xsl:template>
Please help me changing the parent tag name from "Root" to "Batch".
None of the offered solutions really solves the problem: they simply rename an element named "Root" (or even just the top element), without verifying that this element has an "Id" attribute.
wwerner is closest to a correct solution, but renames the parent of the parent.
Here is a solution that has the following properties:
- It is correct.
- It is short.
- It is generalized (the replacement name is contained in a variable).
Here is the code:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="vRep" select="'Batch'"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@Id"/>
<xsl:template match="*[@Id]">
<xsl:element name="{$vRep}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()|text()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@Id" />
<xsl:template match="Root">
<Batch>
<xsl:copy-of select="@*|*|text()" />
</Batch>
</xsl:template>
This should do the job:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()|text()" />
</xsl:copy>
</xsl:template>
<xsl:template match="node()[node()/@Id]">
<batch>
<xsl:apply-templates select='@*|*|text()' />
</batch>
</xsl:template>
<xsl:template match="@Id">
</xsl:template>
</xsl:stylesheet>
I tested with the following XML input:
<root anotherAttribute="1">
<a Id="1"/>
<a Id="2"/>
<a Id="3" anotherAttribute="1">
<b Id="4"/>
<b Id="5"/>
</a>
I would try:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@Id">
</xsl:template>
<xsl:template match="/Root">
<Batch>
<xsl:apply-templates select="@*|node()"/>
</Batch>
</xsl:template>
The first block copies all that is not specified, as you use.
The second replaces @id
with nothing wherever is occurs.
The third renames /Root
to /Batch
.
精彩评论