В случае узлов, которые имеют атрибут @ name , начинающийся с prefix_ , вы можете оставить преобразование идентичности, чтобы выполнить свою работу.Таким образом, вам нужно переопределить регистр только для элементов, которые не имеют @ name , начиная с prefix_ .
<xsl:template match="xs:schema/node()[not(starts-with(@name, 'prefix'))]">
Чтобы скопировать только потомков слюбой атрибут, начинающийся с «prefix_», вам также потребуется скопировать любой узел, который может не иметь атрибута сам по себе, но сам имеет потомка, отвечающего критериям.
<xsl:apply-templates
select="@*|
node()[descendant-or-self::*[count(@*[starts-with(., 'prefix')]) > 0]]"
mode="attr" />
Итак, здесь вы используетеатрибут mode , когда вы применяете шаблоны, так что вы можете переопределить поведение при сопоставлении потомков тоже
<xsl:template match="@*|node()" mode="attr">
Вот полный XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="xs:schema/node()[not(starts-with(@name, 'prefix'))]">
<xsl:if test="descendant-or-self::*[count(@*[starts-with(., 'prefix')]) > 0]">
<xsl:copy>
<xsl:apply-templates select="@*|node()[descendant-or-self::*[count(@*[starts-with(., 'prefix')]) > 0]]" mode="attr" />
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()" mode="attr">
<xsl:copy>
<xsl:apply-templates select="@*[starts-with(., 'prefix')]|node()[descendant-or-self::*[count(@*[starts-with(., 'prefix')]) > 0]]" mode="attr"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Когда применяется к вашему входному XML, вывод будет следующим:
<xml>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<node name="prefix_a">
<element/>
<element attr="asdf"/>
<element attr="prefix_attr"/>
<element battr="prefix_battr"/>
</node>
<node name="prefix_b">
<node>
<element/>
<element battr="prefix_bttr"/>
<element hattr="prefix_cattr"/>
</node>
</node>
<node name="c">
<node>
<node>
<node>
<node>
<element battr="prefix_bttr"/>
<element flattr="prefix_hattr"/>
</node>
</node>
</node>
</node>
</node>
<node name="d">
<element shattr="prefix_shattr"/>
<element cattr="prefix_battr"/>
</node>
</xs:schema>
</xml>