2012-08-14 74 views
1

我正在使用XSL文件來轉換另一個使用Y和N值而不是true和false的XML。我怎麼能一次定義所有的Y或N都應該成爲真或假,而不必在我訪問原始數據的每一行中都做到這一點?用XSL翻譯數據

原始XML:

<whatever> 
<water>N</water> 
<electricity>Y</electricity> 
<internet>Y</internet> 
</whatever> 

XSL,現在我不得不每一次在Y爲真翻譯:

<whatever> 
<water><!-- xsl translation here --></water> 
<electricity><!-- xsl translation here --></electricity> 
<internet><!-- xsl translation here --></internet> 
</whatever> 

理想XSL:

<whatever> 
<!-- Something magic that will automatically change all value-of output--> 
<water><xsl:value-of select="//water"/></water> 
<electricity><xsl:value-of select="//electricity"/></electricity> 
<internet><xsl:value-of select="//internet"/></internet> 
</whatever> 

輸出:

<whatever> 
<water>false</water> 
<electricity>true</electricity> 
<internet>true</internet> 
</whatever> 
+0

*我如何翻譯在我的輸出值的所有實例,而不必做的每一個其中之一?*當然*所有*意味着*每一個*和*每一個*暗示*所有*?如果不是,請澄清。 – 2012-08-14 19:27:03

+0

嗨,像說@HighPerformanceMark你應該澄清,因爲我們可以提供多種方式來處理這個;即使是非xsl之一。 – 2012-08-14 19:31:50

+0

對不起,希望我澄清了它。先謝謝了。 – 2012-08-14 19:52:26

回答

3

一個更簡單,更高效的XSLT 1.0樣式表會...

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

<xsl:template match="@*|node()"> 
<xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
</xsl:copy> 
</xsl:template> 

<xsl:template match="text()[.='Y']"> 
<xsl:value-of select="'true'" /> 
</xsl:template> 

<xsl:template match="text()[.='N']"> 
<xsl:value-of select="'false'" /> 
</xsl:template> 

</xsl:stylesheet> 

...或等價...

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

<xsl:template match="@*|node()"> 
<xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
</xsl:copy> 
</xsl:template> 

<xsl:template match="text()[.='Y']">true</xsl:template> 
<xsl:template match="text()[.='N']">false</xsl:template> 

</xsl:stylesheet> 
1

使用標識模板來處理XML並保持相同的結構。

添加一個將文本節點「Y」和「N」轉換爲true和false的模板。

<?xml version="1.0" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" omit-xml-declaration="yes"/> 

    <!-- put your templates here --> 
<xsl:template match="text()"> 
    <xsl:choose> 
    <xsl:when test=".='Y'">true</xsl:when> 
    <xsl:when test=".='N'">false</xsl:when> 
    <xsl:otherwise><xsl:copy/></xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

    <!-- identity templates --> 
    <xsl:template match="*"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 
      <xsl:apply-templates select="node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="@*|comment()|processing-instruction()"> 
     <xsl:copy/> 
    </xsl:template> 

</xsl:stylesheet> 

關於身份模板的更多信息,請參閱。

1

只需使用

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

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 
<xsl:template match="text()[. = 'Y' or . = 'N']"> 
    <xsl:value-of select=". = 'Y'"/> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔施加這種轉變:

<whatever> 
    <water>N</water> 
    <electricity>Y</electricity> 
    <internet>Y</internet> 
</whatever> 

有用,正確的結果產生

<whatever> 
    <water>false</water> 
    <electricity>true</electricity> 
    <internet>true</internet> 
</whatever> 

說明

  1. 使用並覆蓋identity rule

  2. 所有你想在壓倒一切的模板來輸出簡單的XPath表達式的結果. = 'Y'

+0

在迂腐的風險下,這是另一個,可以說更簡單:相同的模板,但匹配=「text()[。=('Y','N')]」。當然,這隻適用於XSLT 2.0,但值得一提,因爲不清楚OP希望使用哪個版本的XSLT。我承認,簡單性與效率並不是一回事,並且所設置的比較可能與操作符效率較低。 – 2012-08-15 06:46:48

+0

@ SeanB.Durkin,正確。如果他們可以使用可在XSLT 1.0和XSLT 2.0中使用的解決方案,則不需要使用僅限XSLT 2.0的解決方案。 – 2012-08-15 12:43:19