Главная » XSLT » Уплощение иерархии XML

0

Задача

Имеется документ, в котором иерархия элементов имеет больше уровней, чем вам хотелось бы. Требуется выполнить уплощение дерева – избавиться от некото­рых уровней.

Решение

Если ваша цель – убрать лишние уровни вместе с хранящейся там информацией, то можно применить идиому переопределяемого копирования. Во включающей таб­лице стилей должен быть шаблон, который сопоставляется с отбрасываемыми эле­ментами и выполняет команду apply-templates без копирования.

Рассмотрим следующий входной документ, в котором люди разбиты на две категории: salaried и union.

<people> <union> <person>

<firstname>Warren</firstname> <lastname>Rosenbaum</lastname> <age>37</age> <height>5.75</height> </person> <person>

<firstname>Dror</firstname> <lastname>Seagull</lastname> <age>28</age> <height>5.10</height> </person> <person>

<firstname>Mike</firstname> <lastname>Heavyman</lastname> <age>45</age> <height>6.0</height> </person> <person>

<firstname>Theresa</firstname> <lastname>Archul</lastname> <age>37</age> <height>5.5</height> </person> </union> <salaried>

<person>

<firstname>Sal</firstname> <lastname>Mangano</lastname> <age>37</age> <height>5.75</height> </person> <person>

<firstname>Jane</firstname> <lastname>Smith</lastname> <age>28</age> <height>5.10</height> </person> <person>

<firstname>Rick</firstname> <lastname>Winters</lastname> <age>45</age> <height>6.0</height> </person> <person>

<firstname>James</firstname> <lastname>O’Riely</lastname> <age>33</age> <height>5.5</height> </person> </salaried>

</people>

Следующая таблица стилей просто отбрасывает лишние структурные уровни:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:import href="copy.xslt"/>

<xsl:output method="xml" version="1.0" encoding="UTF-8"/>

<xsl:template match="people"> <xsl:copy>

<!— отбрасываем предков элементов person —> <xsl:apply-templates select="*/person" /> </xsl:copy> </xsl:template>

Обсуждение

Наличие дополнительных структурных уровней в документе обычно можно лишь приветствовать, так как это упрощает его обработку с помощью XSLT. Однако, если их слишком много, то документ становится громоздким, и человеку воспринять его слож­но. Людям свойственно делать выводы о логической структуре документа, исходя из его пространственной организации, а не из дополнительной синтаксический разметки.

В примере ниже показано, что дополнительные структурные уровни не избыточны, а несут в себе информацию. Если в процессе уплощения нужно сохранить информацию о структуре, то имеет смысл создать для ее хранения атрибут или дочерний элемент. В следующей таблице стилей создается атрибут:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:import href="copy.xslt"/>

<xsl:output method="xml" version="1.0" encoding="UTF-8" omit-xml-declaration="yes"/>

<!– отбрасываем родителей элементов person –> <xsl:template match="*[person]">

<xsl:apply-templates/> </xsl:template>

<xsl:template match="person"> <xsl:copy>

<xsl:apply-templates select="@*"/> <xsl:attribute name="class">

<xsl:value-of select="local-name(..)"/> </xsl:attribute> <xsl:apply-templates/> </xsl:copy> </xsl:template>

</xsl:stylesheet>

А здесь создается элемент:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:import href="copy.xslt"/> <xsl:strip-space elements="*"/>

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />

<!– отбрасываем родителей элементов person –> <xsl:template match="*[person]">

<xsl:apply-templates/> </xsl:template>

<xsl:template match="person"> <xsl:copy>

<xsl:copy-of select="@*"/> <xsl:element name="class">

<xsl:value-of select="local-name(..)"/> </xsl:element> <xsl:apply-templates/> </xsl:copy> </xsl:template>

</xsl:stylesheet>

Элемент xsl:strip-space и атрибут indent="yes" элемента xsl:output нужны для того, чтобы в выходном файле не было лишних пустых строк, показан­ных ниже:

<people>

<person>

<class>union</class> <firstname>Warren</firstname> <lastname>Rosenbaum</lastname> <age>37</age> <height>5.75</height> </person>

<— Дырка!

<person>

<class>salaried</class> <firstname>Sal</firstname> <lastname>Mangano</lastname> <age>37</age> <height>5.75</height> </person>

</people>

Мангано Сэл  XSLT. Сборник рецептов. – М.: ДМК Пресс, СПБ.: БХВ-Петербург, 2008. – 864 с.: ил.

По теме:

  • Комментарии