2012-11-26 65 views
1

我有幾個信息條目,我想用逗號分隔。但是,每個條目可能都是空的,如果首先出現的條目爲空,則不應出現逗號。例如:使用布爾值在XSLT中格式化字符串

如果我們有四個XSLT參數:姓名,電話號碼,地址,職業

,我們有

  • 名稱:約翰
  • 電話號碼:111-111-1111
  • 地址:虛街道
  • 職業:貝克

那麼最終的字符串應該是:

約翰,111-111-1111,虛街,貝克

如果姓名和電話號碼參數爲空或null,則最終的字符串應該是:

虛街,貝克

如果只有電話號碼null或空,那麼最終的字符串應該是:

約翰,虛街,貝克

在像C#語言,我會寫這樣的代碼:

foreach (EntryObject entry in entryList) 
{ 
    if (firstEntry == true && entry.Type != EntryType.Age && entry.Type != EntryType.Sex) 
    { 
     finalString += entry.ValueString; 
     firstEntry = false; 
    } 
    else if (firstEntry == false && entry.Type != EntryType.Age && entry.Type != EntryType.Sex) 
    { 
     finalString += ", " + entry.ValueString; 
    } 
} 
return finalString; 

不過,我聽說在XSLT變量是不可變的。我應該如何在XSLT中解決這個問題?

編輯: 的XML條目會是這個樣子:

<AddressBook> 
    <PersonalInfo> 
     <Age>33</Age> 
     <Sex>Male</Sex> 
     <Name>John</Name> 
     <PhoneNumber></PhoneNumber> 
     <Address>Imaginary Street</Address> 
     <Occupation>Baker</Occupation> 
    </PersonalInfo> 
</AddressBook> 

注意,某些條目可能是空的,我只會用名,PHONENUMBER,地址和職業。年齡和性別應該被忽略。

+0

什麼是您的XML輸入是什麼樣子? –

+0

這是XSLT 1.0還是XSLT 2.0? –

+0

@MatthewGreen我編輯了我原來的帖子以包含一個例子。 –

回答

2

使用只匹配non-empy元素(string-length(.)>0或簡單地string(.))的XPath條件,然後使用position()函數檢查元素是否是第一個元素。輸入XML:

<root> 
    <item> 
    <name>John</name> 
    <phoneNumber>111-111-1111</phoneNumber> 
    <address>Imaginary street</address> 
    <occupation>Baker</occupation> 
    </item> 
    <item> 
    <name>Jane</name> 
    <address>Another street</address> 
    <occupation>Decorator</occupation> 
    </item> 
    <item> 
    <address>Unknown</address> 
    </item> 
</root> 

XSLT:

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

    <xsl:template match="item"> 
    <textItem> 
     <xsl:for-each select="*[string(.)]"> 
     <xsl:if test="position()>1"> 
      <xsl:text>,</xsl:text> 
     </xsl:if> 
     <xsl:value-of select="."/> 
     </xsl:for-each> 
    </textItem> 
    </xsl:template> 

    <xsl:template match="text()"> 
    </xsl:template> 

    <xsl:template match="root"> 
    <root> 
     <xsl:apply-templates/> 
    </root> 
    </xsl:template> 

</xsl:stylesheet> 

其中第一個模板是一個實際上做的工作,<xsl:template match="text()">刪除(包含在匹配元素的文本默認XSLT處理器會複製這樣的文本到輸出)並且<xsl:template match="root">生成輸出文檔的根元素。

結果:

<root> 
    <textItem>John,111-111-1111,Imaginary street,Baker</textItem> 
    <textItem>Jane,Another street,Decorator</textItem> 
    <textItem>Unknown</textItem> 
</root> 

如果你有興趣的只有一些你只是使用UNION運算符(|)選擇它們的字段 - 例如如果你只想要電話,在例如地址和職業上述修改XSLT是:

<xsl:template match="item"> 
    <textItem> 
     <xsl:for-each select="(phoneNumber|address|occupation)[string(.)]"> 
     <xsl:if test="position()>1"> 
      <xsl:text>,</xsl:text> 
     </xsl:if> 
     <xsl:value-of select="."/> 
     </xsl:for-each> 
    </textItem> 
    </xsl:template> 

    <xsl:template match="text()"> 
    </xsl:template> 

    <xsl:template match="root"> 
    <root> 
     <xsl:apply-templates/> 
    </root> 
    </xsl:template> 

</xsl:stylesheet> 
+0

謝謝你的回答,但在檢查了給我的xml後,我意識到還有其他元素,我不使用該元素 - 例如在下會有年齡,性別,姓名,電話號碼,地址和職業,我只會使用姓名,電話號碼,地址和職業 - 所以這種檢查position()> 1的策略是行不通的。不幸的是,我無法控制給定的XML。 –

+0

它仍然可以工作 - 請參閱上面的精選答案。 – MiMo

+0

什麼是 for? –

2

這裏是接受的「列入黑名單」的元素名作爲參數列表中的一個通用的解決方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pIgnoreThese" select="' Age Sex '"/> 

<xsl:template match="PersonalInfo"> 
    <xsl:apply-templates select= 
    "*[normalize-space() 
    and 
     not(contains($pIgnoreThese, concat(' ', name(), ' '))) 
    ]"/> 
    <xsl:text>&#xA;</xsl:text> 
</xsl:template> 

<xsl:template match="PersonalInfo/*"> 
    <xsl:if test="position() >1">, </xsl:if> 
    <xsl:value-of select="."/> 
</xsl:template> 
</xsl:stylesheet> 

當這個變換所提供的XML文檔應用:

<AddressBook> 
     <PersonalInfo> 
      <Age>33</Age> 
      <Sex>Male</Sex> 
      <Name>John</Name> 
      <PhoneNumber>111-111-1111</PhoneNumber> 
      <Address>Imaginary Street</Address> 
      <Occupation>Baker</Occupation> 
     </PersonalInfo> 
     <PersonalInfo> 
      <Age>33</Age> 
      <Sex>Male</Sex> 
      <Name></Name> 
      <PhoneNumber></PhoneNumber> 
      <Address>Imaginary Street</Address> 
      <Occupation>Baker</Occupation> 
     </PersonalInfo> 
     <PersonalInfo> 
      <Age>33</Age> 
      <Sex>Male</Sex> 
      <Name>John</Name> 
      <PhoneNumber></PhoneNumber> 
      <Address>Imaginary Street</Address> 
      <Occupation>Baker</Occupation> 
     </PersonalInfo> 
</AddressBook> 

的希望,正確的結果產生

John, 111-111-1111, Imaginary Street, Baker 
Imaginary Street, Baker 
John, Imaginary Street, Baker