Ни одно из предложенных решений не решает проблему : они просто переименовывают элемент с именем «Корень» (или даже просто верхний элемент) без проверка наличия у этого элемента атрибута «Id».
wwerner наиболее близок к правильному решению, но переименовывает родительский элемент.
Вот решение, которое имеет следующие свойства :
Вот код:
<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>
Это должно сработать:
<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>
Я тестировал со следующим вводом XML:
<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
.