2012-05-20 43 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