2012-05-20 46 views
3

我正在嘗試編寫一個可以幫助從另一個XML文檔過濾數據的文檔。例如。使用自定義標記語言過濾XML數據

<document> 
    <filter> 
     <what> 
      <include> 
       <marital_staus/> 
       <ms>single</ms> <!--nog = no of groups--> 
       <include> 
        <memberofgroups/> 
        <gn>Football club</gn> <!--user is a member of this club--> 
       </include> 
      </include> 
     </what> 
    </filter> 

    <users> 
      <user> 
       <name> 
        <first>abc</first> 
        <last>xyz</last> 
       </name> 
       <dob>12/02/1987</dob> 
       <marital_status>married</marital_status> 
       <groups> 
        <member_of_group>Chess Club</member_of_group> 
        <member_of_group>Football club</member_of_group> 
       </groups> 
      </user> 

      <user> 
       <name> 
        <first>aaa</first> 
        <last>bbb</last> 
       </name> 
       <dob>14/03/1987</dob> 
       <marital_status>single</marital_status> 
       <groups> 
        <member_of_group>Chess Club</member_of_group> 
        <member_of_group>Football club</member_of_group> 
       </groups> 
      </user> 

      <user> 
       <name> 
        <first>fff</first> 
        <last>nnn</last> 
       </name> 
       <dob>12/6/1983</dob> 
       <marital_status>single</marital_status> 
       <groups> 
        <member_of_group>Chess Club</member_of_group> 
        <member_of_group>Cultural Association</member_of_group> 
       </groups> 
      </user> 
    </users> 
</document> 

我想這段代碼做的是選擇,第一,誰是足球俱樂部的成員,然後掉那些的用戶,選擇誰是單一的用戶。但我無法弄清楚如何爲此編寫樣式表。我寫這個:

<xsl:template name="temp"> 
     <xsl:param name="a1"/> 
     <xsl:param name="pro"/> 
     <xsl:choose> 
      <xsl:when test="$pro = 'marital_status'"> 
       <xsl:for-each select="/document/users/user"> 
        <xsl:if test="marital_status=$a1"> 
         <xsl:value-of select="."/> 
        </xsl:if>     
       </xsl:for-each> 
      </xsl:when> 
      <xsl:when test="$pro = 'memberofgroups'"> 
      <xsl:for-each select="/document/users/user"> 
       <xsl:for-each select="./groups/member_of_group"> 
        <xsl:if test=".=$a1"> 
         <xsl:value-of select="."/> 
        </xsl:if> 
       </xsl:for-each> 
      </xsl:for-each> 
     </xsl:when> 
     </xsl:choose> 
    </xsl:template> 
<xsl:template match="include"> 
     <xsl:call-template name="temp"> 
      <xsl:with-param name="a1"> 
       <xsl:apply-templates select="*[2]"/> 
      </xsl:with-param> 
     </xsl:call-template> 
    </xsl:template> 

在調用模板時,我傳遞正確的值,我想。

問題是我得到所有單身用戶以及所有屬於該特定羣體成員的用戶。不過,我希望單身用戶也是足球俱樂部的成員。我不希望樣式表被硬編碼,因爲我也想基於其他元素進行過濾。

我無法弄清楚如何將過濾的元素保存到可用作下一個XPath表達式的輸入的內容中。或者我在編寫用於過濾文檔的約束時犯了一些錯誤。或者有沒有其他更適當的方式來編寫文件進行過濾?我會非常感謝你的幫助。

+0

是否使用任何其他語言來調用這些模板? –

+0

不...我只使用xslt ...然後我有一個XML文件,其中有兩個元素一個「過濾器」第二個「用戶」...用戶有一些數據元素,如名稱,dob等,我想這個過濾元素使用此樣式表或任何其他適當的過濾來自用戶元素的數據 – ashamim

+0

您忘記提供源XML文檔。請編輯問題並提供這些重要信息。 –

回答

1

用途:

/*/*/user 
    [*[name() = name(/*/filter/*/include/*[1])] 
    = 
     /*/filter/*/include/*[2] 
    and 
     groups/*[name() = name(/*/filter/*/include/include/*[1])] 
    = 
     /*/filter/*/include/include/*[2] 
    ] 

XSLT - 基於驗證:

<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= 
     "/*/*/user 
     [*[name() = name(/*/filter/*/include/*[1])] 
     = 
      /*/filter/*/include/*[2] 
     and 
      groups/*[name() = name(/*/filter/*/include/include/*[1])] 
     = 
      /*/filter/*/include/include/*[2] 
     ] 
"/> 
</xsl:template> 
</xsl:stylesheet> 

當這種變換所提供的XML文檔應用(有幾個錯別字更正):

<document> 
    <filter> 
     <what> 
      <include> 
       <marital_status/> 
       <ms>single</ms> 
       <!--nog = no of groups--> 
       <include> 
        <member_of_group/> 
        <gn>Football club</gn> 
        <!--user is a member of this club--> 
       </include> 
      </include> 
     </what> 
    </filter> 
    <users> 
     <user> 
      <name> 
       <first>abc</first> 
       <last>xyz</last> 
      </name> 
      <dob>12/02/1987</dob> 
      <marital_status>married</marital_status> 
      <groups> 
       <member_of_group>Chess Club</member_of_group> 
       <member_of_group>Football club</member_of_group> 
      </groups> 
     </user> 
     <user> 
      <name> 
       <first>aaa</first> 
       <last>bbb</last> 
      </name> 
      <dob>14/03/1987</dob> 
      <marital_status>single</marital_status> 
      <groups> 
       <member_of_group>Chess Club</member_of_group> 
       <member_of_group>Football club</member_of_group> 
      </groups> 
     </user> 
     <user> 
      <name> 
       <first>fff</first> 
       <last>nnn</last> 
      </name> 
      <dob>12/6/1983</dob> 
      <marital_status>single</marital_status> 
      <groups> 
       <member_of_group>Chess Club</member_of_group> 
       <member_of_group>Cultural Association</member_of_group> 
      </groups> 
     </user> 
    </users> 
</document> 

以上的XPath表達式,並且所選擇的節點(在這種情況下只是一個單一的節點)被複制到輸出

<user> 
    <name> 
     <first>aaa</first> 
     <last>bbb</last> 
    </name> 
    <dob>14/03/1987</dob> 
    <marital_status>single</marital_status> 
    <groups> 
     <member_of_group>Chess Club</member_of_group> 
     <member_of_group>Football club</member_of_group> 
    </groups> 
</user> 
+0

難道有任何可能的方式使這個樣式表結構獨立嗎?例如如果我寫我的濾波約束像 足球俱樂部 正如我已經改變了位置這個樣式表將n的標籤工作還是你認爲我將不得不改變我爲過濾制定限制的方式。 – ashamim

+0

@ashamim:如果刪除'groups'元素,則選擇會更容易。這就是說,我認爲在同一個XML文檔中的「過濾器」與要搜索的內容不同是有意義的。 –

+0

我打算爲各種類似文檔分別使用此濾鏡元素。現在我在同一個XML文檔中使用它來檢查是否可以成功應用不同的過濾約束。 – ashamim