Атрибутами считаются пропавшими без вести после сортировки элементов
Мне нужно создать таблицу стилей XSLT 2.0, которая обрабатывает полную периодическую таблицу , сортирует атомы (только их имена) в группы на основе их состояния (т. е. STATE
атрибут элемента ATOM
) в текстовый файл.
<ATOM>
без атрибутов STATE
. Эти элементы также должны присутствовать в итоговом документе.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="PERIODIC_TABLE">
<xsl:for-each-group select="ATOM" group-by="@STATE" >
<xsl:text> ** </xsl:text>
<xsl:value-of select="current-grouping-key()"/>
<xsl:text>
</xsl:text>
<xsl:for-each select="current-group()">
<xsl:sort select="NAME"/>
<xsl:value-of select="NAME"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
2 ответа:
Я лишь слегка коснулся вашего кода, сделав следующее изменение :
Заменить:
group-by="@STATE"
С:
group-by="(@STATE, 'UNKNOWN')[1]"
Преобразование теперь :
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="PERIODIC_TABLE"> <xsl:for-each-group select="ATOM" group-by="(@STATE, 'UNKNOWN')[1]" > <xsl:text> ** </xsl:text> <xsl:value-of select="current-grouping-key()"/> <xsl:text> </xsl:text> <xsl:for-each select="current-group()"> <xsl:sort select="NAME"/> <xsl:value-of select="NAME"/> <xsl:text> </xsl:text> </xsl:for-each> <xsl:text> </xsl:text> </xsl:for-each-group> </xsl:template> </xsl:stylesheet>
И желаемый, правильный результат получается :
** UNKNOWN Actinium Aluminum Americium Antimony Arsenic Astatine Barium Berkelium Beryllium Bohrium Boron Bromine Cadmium Calcium Californium Cerium Cesium Chlorine Chromium Cobalt Copper Curium Dubnium Dysprosium Einsteinium Erbium Europium Fermium Fluorine Francium Gadolinium Gallium Germanium Hafnium Hassium Holmium Indium Iodine Iridium Iron Krypton Lanthanum Lawrencium Lead Lithium Lutetium Magnesium Manganese Meitnerium Mendelevium Mercury Molybdenum Neodymium Neon Neptunium Nickel Niobium Nitrogen Nobelium Osmium Oxygen Palladium Phosphorus Platinum Plutonium Polonium Potassium Praseodymium Promethium Protactinium Radium Radon Rhenium Rhodium Rubidium Ruthenium Rutherfordium Samarium Scandium Seaborgium Selenium Silicon Silver Sodium Strontium Sulfur Tantalum Technetium Tellurium Terbium Thallium Thorium Thulium Tin Titanium Tungsten Uranium Vanadium Ytterbium Yttrium Zinc Zirconium ununbium ununnilium unununium ** GAS Argon Helium Hydrogen Xenon ** SOLID Bismuth Carbon Gold
Вы можете просто сделать
xsl:for-each
для всех атомов, которые не имеют атрибута состояния. Вы могли бы разграничить это с чем-то вроде "другого".Эта измененная версия вашей таблицы стилей:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="PERIODIC_TABLE"> <xsl:for-each-group select="ATOM" group-by="@STATE"> <xsl:text> ** </xsl:text> <xsl:value-of select="current-grouping-key()"/> <xsl:text>
</xsl:text> <xsl:for-each select="current-group()"> <xsl:sort select="NAME" case-order="#default"/> <xsl:value-of select="NAME"/> <xsl:text>
</xsl:text> </xsl:for-each> <xsl:text>
</xsl:text> </xsl:for-each-group> <xsl:if test="ATOM[not(@STATE)]"> <xsl:text> ** OTHER
</xsl:text> <xsl:for-each select="ATOM[not(@STATE)]"> <xsl:sort select="NAME" case-order="#default"/> <xsl:value-of select="NAME"/> <xsl:text>
</xsl:text> </xsl:for-each> </xsl:if> </xsl:template> </xsl:stylesheet>
Выдает следующий результат (во всей красе):
Несколько других вещей, которые я сделал, это добавил атрибуты** GAS Argon Helium Hydrogen Xenon ** SOLID Bismuth Carbon Gold ** OTHER Actinium Aluminum Americium Antimony Arsenic Astatine Barium Berkelium Beryllium Bohrium Boron Bromine Cadmium Calcium Californium Cerium Cesium Chlorine Chromium Cobalt Copper Curium Dubnium Dysprosium Einsteinium Erbium Europium Fermium Fluorine Francium Gadolinium Gallium Germanium Hafnium Hassium Holmium Indium Iodine Iridium Iron Krypton Lanthanum Lawrencium Lead Lithium Lutetium Magnesium Manganese Meitnerium Mendelevium Mercury Molybdenum Neodymium Neon Neptunium Nickel Niobium Nitrogen Nobelium Osmium Oxygen Palladium Phosphorus Platinum Plutonium Polonium Potassium Praseodymium Promethium Protactinium Radium Radon Rhenium Rhodium Rubidium Ruthenium Rutherfordium Samarium Scandium Seaborgium Selenium Silicon Silver Sodium Strontium Sulfur Tantalum Technetium Tellurium Terbium Thallium Thorium Thulium Tin Titanium Tungsten ununbium ununnilium unununium Uranium Vanadium Ytterbium Yttrium Zinc Zirconium
case-order
к элементамxsl:sort
, и я использовал ссылку на шестнадцатеричную сущность

для новых строк.Еще одна вещь, которую я обычно делаю, но не сделал здесь, - это использование
concat()
вместо того, чтобы иметь отдельныйxsl:text
для новых строк / пробелов.Вместо этого:
<xsl:value-of select="NAME"/> <xsl:text>
</xsl:text>
Вы можете сделать это:
<xsl:value-of select="concat(NAME,'
')"/>