2012-12-03 97 views
1

任何人都可以建議我如何使用xslt實現以下功能嗎?在xslt中做if if條件匹配

這是XML輸入:

<output> 
    <header> 
     <someId>ABC123</someId> 
</header> 
<results> 
    <product id="A"> 
    <externalId>XYZ666</externalId> 
    <title>some title a</title> 
    </product> 
    <product id="B"> 
    <externalId>ABC123</externalId> 
    <title>some title b</title> 
    </product> 
    <product id="C"> 
    <externalId>666777</externalId> 
    <title>some title c</title> 
    </product> 
</results> 
</output> 

我需要的是一個XSLT將只返回「產品」,其具有匹配\頭\ someId那裏是一個,否則\產品\外部ID它匹配所有\ product元素。

任何建議非常感謝。

回答

0

w3schools的教程是一個很好的起點!

試着看看this頁面!

+3

請不要鏈接到w3schools,這是在StackOverflow廣泛不喜歡(見http://w3fools.com爲什麼)。你可能已經鏈接到一個包含正確信息的頁面,但該網站有很多不正確的和誤導性的信息 - 並以任何方式鏈接到w3schools使其信譽**不**應得的。 (如果您使用Google搜索,並且擁有Google帳戶,則可以[輕鬆阻止搜索結果](來自w3school的http://support.google.com/websearch/bin/answer.py?hl=zh_CN&answer=1210386)) – freefaller

0
<xsl:key name="by-id" match="product" use="externalId"/> 

<xsl:template match="/"> 
    <xsl:variable name="ref" select="key('by-id', //header/someId)"/> 
    <xsl:choose> 
    <xsl:when test="$ref"> 
     <xsl:copy-of select="$ref"/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:copy-of select="//product"/> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

顯示如何使用密鑰來交叉引用節點。

+0

好。 '當'情況總是失敗!由於某種原因。 –

+0

對不起,我在'匹配'模式中有一個錯字,現在我會糾正這個錯誤。 –

1

您應該使用<xsl:when test="condition"> ..

爲XML我提供樣品XSLT代碼,選擇有條件的節點..

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="results/product"> 
    <xsl:choose> 
     <xsl:when test="externalId = /output/header/someId"> 
     <!--Here goes the code--> 
     <something></something> 
     </xsl:when> 
     <xsl:otherwise> 
     <!--Other code --> 
     <somethingelse></somethingelse> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

上面的代碼的行爲就像..

if ("externalId = /output/header/someId") then 
     <!--Here goes the code--> 
     <something></something> 
else 
     <!--Other code --> 
     <somethingelse></somethingelse> 

使用縮進模板重寫!

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="results/product[externalId = /output/header/someId]"> 
    <!--Here goes the code--> 
    <something></something> 
    </xsl:template> 
    <xsl:template match="results/product[externalId != /output/header/someId]"> 
    <!--Here goes the code--> 
    <somethingelse></somethingelse> 
    </xsl:template> 
</xsl:stylesheet> 
1

這樣簡單 - 不變量,沒有xsl:chose,沒有xsl:when,沒有xsl:otherwise

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/"> 
    <xsl:copy-of select= 
    "/*[header/someId]/results/product[externalId=/*/header/someId] 
    | 
     /*[not(header/someId)]/results/product 
    "/> 
</xsl:template> 
</xsl:stylesheet> 

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

<output> 
    <header> 
     <someId>ABC123</someId> 
</header> 
<results> 
    <product id="A"> 
    <externalId>XYZ666</externalId> 
    <title>some title a</title> 
    </product> 
    <product id="B"> 
    <externalId>ABC123</externalId> 
    <title>some title b</title> 
    </product> 
    <product id="C"> 
    <externalId>666777</externalId> 
    <title>some title c</title> 
    </product> 
</results> 
</output> 

的希望,正確的結果產生

<product id="B"> 
    <externalId>ABC123</externalId> 
    <title>some title b</title> 
</product> 

當同樣的變換被應用到這個XML文檔:

<output> 
<results> 
    <product id="A"> 
    <externalId>XYZ666</externalId> 
    <title>some title a</title> 
    </product> 
    <product id="B"> 
    <externalId>ABC123</externalId> 
    <title>some title b</title> 
    </product> 
    <product id="C"> 
    <externalId>666777</externalId> 
    <title>some title c</title> 
    </product> 
</results> 
</output> 

再次通緝,正確的結果產生:

<product id="A"> 
    <externalId>XYZ666</externalId> 
    <title>some title a</title> 
</product> 
<product id="B"> 
    <externalId>ABC123</externalId> 
    <title>some title b</title> 
</product> 
<product id="C"> 
    <externalId>666777</externalId> 
    <title>some title c</title> 
</product> 

說明

我們使用一個通用的方法來選擇一個節點集合(由表達式Exp1)當給定的條件someConditiontrue(),並選擇另一節點集合(由表達式Exp2)時相同的條件下是false()

這兩個表達式是聯合編輯的,每個表達式都可以在兩個互斥的條件下選擇一個節點,因此,根據條件的值,只有一個表達式可以選擇一個節點。

Exp1[someCondition] | Exp2[not(someCondition)] 
+0

我更喜歡身份重寫! :) –

+0

@ InfantProgrammer'Aravind',緊湊性(較短且具有較少數量的線/移動部件)是DRY(「不要重複自己」)原則中的一個要求,即SOLID中的「D」編程範例。這也是KISS(「保持簡單,愚蠢」)原則的要求。好處是更好的可讀性和可理解性,更不容易出錯並且更易於維護。 –

+0

同意!我想補充一點:copy-of select =「Node()」並不會影響模板重寫! (例如:在上面的代碼中,如果我添加''它根本不會被執行!!) –