测试 XML 节点集的每次出现,而不仅仅是第一次



我正在尝试根据课程所在的地区过滤课程列表。但目前,它仅与列表中的第一个位置匹配。

代码是:

<xsl:param name="r" />
<xsl:variable name="RegionList">
  <Region>
    <RegionID>EAST</RegionID>
    <RegionName>Eastern Region</RegionName>
    <Campuses>ABC, XYZ, PQR, WTF</Campuses>
  </Region>
[...]
</xsl:variable>
<xsl:for-each select="CourseItem">
  <xsl:for-each select="//CampusItem">
    <xsl:if test="((normalize-space($r) = '') or contains(msxsl:node-set($RegionList)/Region[RegionID=$r]/Campuses, .//OrganisationID))">
      <xsl:value-of select="CourseID"/>
    </xsl:if>
  </xsl:for-each>
</xsl:for-each>

$r是要搜索的区域。如果留空,则应返回所有区域。

$RegionList/Region[]/Campuses是属于指定区域的校园代码的逗号分隔列表。

OrganisationID是 XML 中的校园字段。

XML 示例:

 <CourseItem>
   <CourseID>C001</CourseID>
   [...]
   <Campus>
     <CampusItem>
       <OrganisationID>OMG</OrganisationID>
       [...]
     </CampusItem>
     <CampusItem>
       <OrganisationID>ABC</OrganisationID>
       [...]
     </CampusItem>
     <CampusItem>
       <OrganisationID>XYZ</OrganisationID>
       [...]
     </CampusItem>
   </Campus>
 </CourseItem>
 <CourseItem>
   <CourseID>C002</CourseID>
   [...]
   <Campus>
     <CampusItem>
       <OrganisationID>ZZZ</OrganisationID>
       [...]
     </CampusItem>
     <CampusItem>
       <OrganisationID>YYY</OrganisationID>
       [...]
     </CampusItem>
     <CampusItem>
       <OrganisationID>AAA</OrganisationID>
       [...]
     </CampusItem>
   </Campus>
 </CourseItem>
 <CourseItem>
   <CourseID>C003</CourseID>
   [...]
   <Campus>
     <CampusItem>
       <OrganisationID>BBB</OrganisationID>
       [...]
     </CampusItem>
     <CampusItem>
       <OrganisationID>WTF</OrganisationID>
       [...]
     </CampusItem>
     <CampusItem>
       <OrganisationID>CCC</OrganisationID>
       [...]
     </CampusItem>
   </Campus>
 </CourseItem>

因此,在C001的情况下,测试只是检查第一个OrganisationID,并标记它没有出现在东部地区,即使接下来的2个校区是。它应该找到任何匹配的

期望输出:

 C001
 C003

给定以下测试输入

<CourseItems>
    <CourseItem>
        <CourseID>C001</CourseID>
        <Campus>
            <CampusItem>
                <OrganisationID>XYZ</OrganisationID>
            </CampusItem>
            <CampusItem>
                <OrganisationID>DEF</OrganisationID>
            </CampusItem>
            <CampusItem>
                <OrganisationID>NOT</OrganisationID>
            </CampusItem>
        </Campus>
    </CourseItem>
    <CourseItem>
        <CourseID>C002</CourseID>
        <Campus>
            <CampusItem>
                <OrganisationID>PLO</OrganisationID>
            </CampusItem>
            <CampusItem>
                <OrganisationID>WWW</OrganisationID>
            </CampusItem>
        </Campus>
    </CourseItem>
    <CourseItem>
        <CourseID>C003</CourseID>
        <Campus>
            <CampusItem>
                <OrganisationID>DNA</OrganisationID>
            </CampusItem>
            <CampusItem>
                <OrganisationID>GHI</OrganisationID>
            </CampusItem>
        </Campus>
    </CourseItem>
</CourseItems>

以下样式表:

XSLT 1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:param name="region" select="'EAST'"/>
<xsl:variable name="campuses">
    <region id="EAST">
        <campus>ABC</campus>
        <campus>DEF</campus>
        <campus>GHI</campus>
    </region>
</xsl:variable>
<xsl:template match="/">
        <xsl:for-each select="CourseItems/CourseItem[Campus/CampusItem/OrganisationID=exsl:node-set($campuses)/region[@id=$region]/campus]">
            <xsl:value-of select="CourseID"/>
            <xsl:if test="position()!=last()">
                <xsl:text>&#10;</xsl:text>
            </xsl:if>
        </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

将返回:

C001
C003

您没有提供完整的 XSLT,所以我不确定这种方法是否适合您。另请注意,我没有使用 msxsl 命名空间,但您可以根据自己的设置对其进行调整。遵循 XSLT

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" doctype-public="XSLT-compat"
 omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
   <xsl:template match="/">
      <xsl:apply-templates>
        <xsl:with-param name="r" select="'EAST'"/>
      </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="CourseItem">
    <xsl:param name="r" />
    <xsl:variable name="RegionList">
      <Region>
        <RegionID>EAST</RegionID>
        <RegionName>Eastern Region</RegionName>
        <Campuses>ABC, XYZ, PQR, WTF</Campuses>
      </Region>
    </xsl:variable>
    <xsl:for-each select="Campus/CampusItem">
      <xsl:if test="((normalize-space($r) = '') or
    contains($RegionList/Region[RegionID=$r]/Campuses,
    OrganisationID))">
        <xsl:copy-of select="."/>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>
</xsl:transform>

应用于示例输入 XML 时

<CourseItem>
  <CourseID>C001</CourseID>
  <Campus>
     <CampusItem>
       <OrganisationID>OMG</OrganisationID>
     </CampusItem>
     <CampusItem>
       <OrganisationID>ABC</OrganisationID>
     </CampusItem>
     <CampusItem>
       <OrganisationID>XYZ</OrganisationID>
     </CampusItem>
  </Campus>
</CourseItem>

产生输出

<CampusItem>
  <OrganisationID>ABC</OrganisationID>
</CampusItem>
<CampusItem>
  <OrganisationID>XYZ</OrganisationID>
</CampusItem>

由于完整的 XSLT 不在问题中,也许只是

<xsl:for-each select="Campus/CampusItem">
...

不见了。

相关内容

  • 没有找到相关文章

最新更新