Используя один из самых фундаментальных и мощных шаблонов проектирования XSLT: переопределяя шаблон идентификации , вы запишете это очень простое преобразование, чтобы заменить каждый элемент «Жанры» на «Темы». "элемент:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Genres">
<Topics>
<xsl:apply-templates select="node()|@*"/>
</Topics>
</xsl:template>
</xsl:stylesheet>
Применительно к предоставленному исходному документу XML:
<Collection>
<DVD>
<ID>0000502461</ID>
<Title>Cirque du Soleil: Alegría</Title>
<Released>2002-05-31</Released>
<RunningTime>90</RunningTime>
<Genres>
<Genre>Family</Genre>
<Genre>Music</Genre>
</Genres>
<Overview>What if anything were possible? What if ... </Overview>
<Notes/>
<Tags>
<Tag Name="Kids" FullName="Kids"/>
</Tags>
</DVD>
</Collection>
Требуемый результат получен:
<Collection>
<DVD>
<ID>0000502461</ID>
<Title>Cirque du Soleil: Alegría</Title>
<Released>2002-05-31</Released>
<RunningTime>90</RunningTime>
<Topics>
<Genre>Family</Genre>
<Genre>Music</Genre>
</Topics>
<Overview>What if anything were possible? What if ... </Overview>
<Notes/>
<Tags>
<Tag Name="Kids" FullName="Kids"/>
</Tags>
</DVD>
</Collection>
Первый шаблон в таблице стилей - это правило идентификации. Он копирует любой сопоставленный узел без изменений и рекурсивно применяет шаблоны к его атрибутам или дочерним элементам. Если другой шаблон отсутствует, этот шаблон создает идентичную копию исходного XML-документа, отсюда и его имя.
Когда существует более конкретный шаблон (определяющий более конкретные детали для сопоставляемого узла, такие как имя и / или другие условия), говорят, что он «переопределяет» более общие шаблоны. Это означает, что для обработки узла выбран более конкретный шаблон.
Используя этот чрезвычайно мощный шаблон проектирования, тривиально реализовать такую обработку как:
- Удалить все узлы, которые удовлетворяют некоторому условию.
- Переименуйте все узлы, которые удовлетворяют некоторому условию.
- Изменить содержимое всех узлов, которые удовлетворяют некоторому условию
при копировании всех остальных узлов без изменений.
В нашем случае второй шаблон более конкретен, и он выбирается для обработки каждого элемента с именем «Жанры». Все, что он делает, это создает элемент с именем «Темы» и внутри него применяет шаблоны ко всем текущим атрибутам узла и дочерним элементам.
Наконец, , следующее преобразование добавит новый элемент "Genre" к потомкам "Genres" для каждого элемента "Tag" :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Genres">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<xsl:apply-templates select="../Tags/Tag" mode="Gen"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Tag" mode="Gen">
<Genre>
<xsl:value-of select="@Name"/>
</Genre>
</xsl:template>
</xsl:stylesheet>
Результат снова соответствует требованию:
<Collection>
<DVD>
<ID>0000502461</ID>
<Title>Cirque du Soleil: Alegría</Title>
<Released>2002-05-31</Released>
<RunningTime>90</RunningTime>
<Genres>
<Genre>Family</Genre>
<Genre>Music</Genre>
<Genre>Kids</Genre>
</Genres>
<Overview>What if anything were possible? What if ... </Overview>
<Notes/>
<Tags>
<Tag Name="Kids" FullName="Kids"/>
</Tags>
</DVD>
</Collection>
Можно найти больше фрагментов кода, использующих шаблон «правила идентификации» здесь .