3

我正在尝试编写一个可以帮助过滤来自另一个 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>

我希望这段代码首先选择是 Football club 成员的用户,然后从这些用户中选择单身用户。但我不知道如何为此编写样式表。我写了这个:

<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 表达式的输入的东西中。或者我在编写过滤文档的约束时犯了一些错误。或者还有其他更合适的方式来编写过滤文档吗?我将非常感谢您的帮助。

4

1 回答 1

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>
于 2012-05-21T02:31:22.923 回答