我有以下XML文档,其中包含两个基本元素:
每个健康中心和活动都包含成员身份。
XML
<root>
<centers>
<center>
<name>Santa Clara</name>
<members>
<member id="1000020001"/>
<member id="1000020002"/>
<member id="1000020005"/>
</members>
</center>
<center>
<name>San Jose</name>
<members>
<member id="1000020003"/>
</members>
</center>
<center>
<name>Sunnyvale</name>
<members>
<member id="1000020004"/>
</members>
</center>
</centers>
<activities>
<activity name="yoga" start="2016-10-12" end="2016-12-17">
<members>
<member id="1000020001"/>
</members>
</activity>
<activity name="spinning" start="2017-10-12" end="2017-12-17">
<members>
<member id="1000020001"/>
<member id="1000020002"/>
</members>
</activity>
<activity name="box" start="2017-10-12" end="2017-12-17">
<members>
<member id="1000020003"/>
</members>
</activity>
<activity name="bachata" start="2017-10-12" end="2017-12-17">
<members>
<member id="1000020004"/>
</members>
</activity>
</activities>
</root>
我正在使用第二个XML文档,它可以处理规则以获取这些健康中心的更多信息:
规则XML
<Evaluation>
<query score="0.25">
<rules>
<rule>yoga</rule>
<rule>spinning</rule>
</rules>
</query>
<query score="1">
<rules>
<rule>box</rule>
</rules>
</query>
</Evaluation>
我需要使用此XML来为与我的活动匹配的健康中心打分:
示例:
我在下面创建了XSL,但是由于XSL功能行为的性质,我不能在循环中加起来并返回值以便每个成员再次添加。
问题:
a)我无法遍历每个成员并将结果添加到中心的所有成员。
b)当查询有多个兴趣(瑜伽和旋转)时,如何使用xpath匹配多个规则。现在我用这个:
$Evaluation/Evaluation/query/rules/rule[text()=$rule_name]
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- use key to extract node information -->
<xsl:key name="activity-key" match="activity" use="members/member/@id" />
<xsl:variable name="Evaluation" select=" document('Evaluation.xml')"/>
<!-- match root document -->
<xsl:template match="/root">
<!-- process each center in document -->
<xsl:for-each select="centers/center">
<!-- create reference per center: -->
<b><xsl:value-of select="center-name"/></b>
<xsl:for-each select="members/member">
member: <xsl:value-of select="@id" />
<xsl:for-each select="key('activity-key', @id)">
-activity: <xsl:value-of select="@name" />
<xsl:call-template name="calculate">
<xsl:with-param name="rule_name" select="@name"/>
</xsl:call-template>
<div/>
</xsl:for-each>
<div/>
</xsl:for-each>
<div/>
</xsl:for-each>
</xsl:template>
<xsl:template name="calculate">
<xsl:param name="rule_name"/>
<xsl:variable name="match_rule" select="$EvaluationML/EvaluationML/query/rules/rule[text()=$rule_name]"/>
<xsl:variable name="matches" select="count($match_interest)"/>
<xsl:for-each select="$Evaluation/Evaluation/query">
<xsl:variable name="query_score" select="@score"/>
score: <b> <xsl:value-of select="$query_score * $matches"/></b>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
我建议你尝试这个作为起点:
<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="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:param name="rules" select="'Rules.xml'"/>
<xsl:key name="activities" match="activity" use="members/member/@id" />
<xsl:template match="/root">
<body>
<xsl:for-each select="centers/center">
<xsl:variable name="member-ids" select="members/member/@id" />
<xsl:variable name="points">
<xsl:for-each select="key('activities', $member-ids)">
<xsl:variable name="score" select="document($rules)/Evaluation/query[rules/rule=current()/@name]/@score" />
<xsl:variable name="count" select="count(members/member[@id=$member-ids])" />
<value>
<xsl:choose>
<xsl:when test="$score">
<xsl:value-of select="$score * $count"/>
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</value>
</xsl:for-each>
</xsl:variable>
<h3>
<xsl:value-of select="name"/>
</h3>
<p>Score: <xsl:value-of select="sum(exsl:node-set($points)/value)"/></p>
</xsl:for-each>
</body>
</xsl:template>
</xsl:stylesheet>
应用于您的示例输入(正确关闭members
元素后!),结果将是:
<body>
<h3>Santa Clara</h3>
<p>Score: 0.75</p>
<h3>San Jose</h3>
<p>Score: 1</p>
<h3>Sunnyvale</h3>
<p>Score: 0</p>
</body>