2013-06-24 37 views
0

我正在嘗試在xml中使用查找表進行xsl轉換。我熟悉xsl,而不關心查找表的物理加載和查詢,相反,我無法用稀疏填充的查找來制定適當的XPath。Xml查找表

我將使用一個表,如果lookup屬性丟失,將需要回退到默認值。下面的XML是這種人口的一個例子:

<?xml version="1.0" encoding="UTF-8"?> 
<codes> 
    <code id="12" country="ca" areacode="420" division="45"/> 
    <code id="13" country="ca" areacode="519" division="45"/> 
    <code id="14" country="ca" areacode="519" division="40"/> 
    <code id="15" country="ca" division="46"/> 
    <code id="16" country="ca"/> 
    <code id="17" country="au"/> 
    <code id="18" country="au" division="32"/> 
</codes> 

當做查找時,我會輸入國家,地區代碼和司,找到適當的ID。

我已經嘗試了幾個選項,但沒有一個是令人滿意的。以下的XPath將返回兩個條目(我應該得到的15號):

/codes/code[@country='ca' and (@areacode='222' or empty(@areacode)) and (@division='46' or empty(@division))]/@id 

的XPath 2.0在我的XSL支持。

任何援助將不勝感激!

回答

3

如果我理解您的要求正確,則@country總是存在的,所以我們可以做的是屬性的關鍵基礎查找。對於其他兩個屬性@areacode@division你要採取哪些具有兩個屬性優先於一個code其具有優先於code有任何匹配的屬性一個匹配屬性匹配code

所以我會簡單地創建不同的優先級的順序,並採取發現第一種:

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

<xsl:param name="lkp-url" select="'test2013062402.xml'"/> 
<xsl:variable name="lkp-doc" select="doc($lkp-url)"/> 

<xsl:key name="by-country" 
     match="code" 
     use="@country"/> 

<xsl:param name="c" select="'ca'"/> 
<xsl:param name="ac" select="'222'"/> 
<xsl:param name="d" select="'46'"/> 

<xsl:template match="/"> 
    <xsl:value-of select="(key('by-country', $c, $lkp-doc)[@areacode = $ac and @division = $d], 
         key('by-country', $c, $lkp-doc)[not(@areacode) and @division = $d], 
         key('by-country', $c, $lkp-doc)[@areacode = $ac and not(@division)], 
         key('by-country', $c, $lkp-doc)[not(@areacode) and not(@division)])[1]/@id"/> 
</xsl:template> 

</xsl:stylesheet> 

我不知道是哪兩個屬性具有優先權,你可能要重新洗牌的第二和第三序列中的項目我在代碼中創建如果areacode具有優先權。

上述代碼應縮短至

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

<xsl:param name="lkp-url" select="'test2013062402.xml'"/> 
<xsl:variable name="lkp-doc" select="doc($lkp-url)"/> 

<xsl:key name="by-country" 
     match="code" 
     use="@country"/> 

<xsl:param name="c" select="'ca'"/> 
<xsl:param name="ac" select="'222'"/> 
<xsl:param name="d" select="'46'"/> 

<xsl:template match="/"> 
    <xsl:variable name="cs" select="key('by-country', $c, $lkp-doc)"/> 
    <xsl:value-of select="($cs[@areacode = $ac and @division = $d], 
         $cs[not(@areacode) and @division = $d], 
         $cs[@areacode = $ac and not(@division)], 
         $cs[not(@areacode) and not(@division)])[1]/@id"/> 
</xsl:template> 

</xsl:stylesheet> 
+0

感謝您的響應。基於對我的現實生活場景測試它精美的作品。我會將其添加到我的個人XSL提示Wiki中! – Gavin