2011-11-03 66 views
2

我需要創建處理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> 
+0

那麼你是由國家分組等等很顯然沒有考慮沒有STATE的ATOM元素。您想如何顯示無狀態元素? – FailedDev

回答

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 
+0

不錯!下次我必須在2.0中進行分組時,我將不得不記住這一點。 +1 –

+0

@DevNull:不客氣。 –

+0

'group-by =「(@ STATE,'UNKNOWN')[1]'我不明白這個代碼是如何工作的 – gezgin

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;')"/>