排序元素后缺少属性

时间:2011-11-03 19:26:38

标签: xslt xslt-2.0

我需要创建一个处理full periodic table的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 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

你可以为所有没有STATE属性的ATOM做xsl:for-each。你可以用“OTHER”这样的东西来划定它。

样式表的这个修改版本:

<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>&#xA;</xsl:text>
      <xsl:for-each select="current-group()">
        <xsl:sort select="NAME" case-order="#default"/>
        <xsl:value-of select="NAME"/>
        <xsl:text>&#xA;</xsl:text>
      </xsl:for-each>
      <xsl:text>&#xA;</xsl:text>
    </xsl:for-each-group>
    <xsl:if test="ATOM[not(@STATE)]">
      <xsl:text> **    OTHER&#xA;</xsl:text>
      <xsl:for-each select="ATOM[not(@STATE)]">
        <xsl:sort select="NAME" case-order="#default"/>
        <xsl:value-of select="NAME"/>
        <xsl:text>&#xA;</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元素,并使用&#xA;十六进制实体引用来换行。

我通常做的另一件事但是没有在这里做的是使用concat()而不是为换行符/空格分别xsl:text

而不是:

<xsl:value-of select="NAME"/>
<xsl:text>&#xA;</xsl:text>

你可以这样做:

<xsl:value-of select="concat(NAME,'&#xA;')"/>