我一直在尝试为以下文档编写一个样式表,可以检查所有用户的奖励,并将该用户的名称添加为/ awards / award元素的子元素
<document>
<users>
<user identity="1">
<name>
<first>abc</first>
<last>xyz</last>
</name>
<achievements>
<achievement>Award A</achievement>
<achievement>Award B</achievement>
</achievements>
</user>
<user identity="2">
<name>
<first>123</first>
<last>DEF</last>
</name>
<achievements>
<received>Award A</received>
</achievements>
</user>
<user identity = "3">
<name>
<first>aaa</first>
<last>bbb</last>
</name>
<achievements>
<received>Award B</received>
</achievements>
</user>
</users>
<!--awards-->
<awards>
<award>
<name>Award A</name>
<!--here the list of the users who recieved this award has to be included-->
</award>
<award>
<name>Award B</name>
</award>
</awards>
</document>
我写下了以下不完整的样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="awards/award">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<!--how can i create a list of all users who have this award-->
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我无法弄清楚在模板“奖励/奖励”中编写查询的方式,例如“将所有已获得此奖项的用户添加为名为user的子元素,并将添加元素的值添加为用户“并给出以下输出。如果有人能引导我采用正确的方法,我将非常感激。
<document>
<users>
<user identity="1">
<name>
<first>abc</first>
<last>xyz</last>
</name>
<achievements>
<achievement>Award A</achievement>
<achievement>Award B</achievement>
</achievements>
</user>
<user identity="2">
<name>
<first>123</first>
<last>DEF</last>
</name>
<achievements>
<received>Award A</received>
</achievements>
</user>
<user identity="3">
<name>
<first>aaa</first>
<last>bbb</last>
</name>
<achievements>
<received>Award B</received>
</achievements>
</user>
</users>
<!--awards-->
<awards>
<award>
<name>Award A</name>
<user identity="1">abc xyz</user>
<user identity="2">123 DEF</user>
</award>
<award>
<name>Award B</name>
<user identity="1">abc xyz</user>
<user identity="3">aaa bbb</user>
</award>
</awards>
</document>
提前致谢
答案 0 :(得分:1)
此转化:
<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:key name="kUserByAward" match="user"
use="achievements/*[self::achievement or self::received]"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="award">
<award>
<xsl:apply-templates select="node()"/>
<xsl:apply-templates select="key('kUserByAward', name)" mode="inclusion"/>
</award>
</xsl:template>
<xsl:template match="user" mode="inclusion">
<user>
<xsl:copy-of select="name"/>
</user>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<document>
<users>
<user>
<name>
<first>abc</first>
<last>xyz</last>
</name>
<achievements>
<achievement>Award A</achievement>
<achievement>Award B</achievement>
</achievements>
</user>
<user>
<name>
<first>dsd</first>
<last>sdasdsadsa</last>
</name>
<achievements>
<received>Award A</received>
</achievements>
</user>
<user>
<name>
<first>aaa</first>
<last>bbb</last>
</name>
<achievements>
<received>Award B</received>
</achievements>
</user>
</users>
<!--awards-->
<awards>
<award>
<name>Award A</name>
<!--here the list of the users who recieved this award has to be included-->
</award>
<award>
<name>Award B</name>
</award>
</awards>
</document>
产生(我猜测应该是什么)想要的正确结果:
<document>
<users>
<user>
<name>
<first>abc</first>
<last>xyz</last>
</name>
<achievements>
<achievement>Award A</achievement>
<achievement>Award B</achievement>
</achievements>
</user>
<user>
<name>
<first>dsd</first>
<last>sdasdsadsa</last>
</name>
<achievements>
<received>Award A</received>
</achievements>
</user>
<user>
<name>
<first>aaa</first>
<last>bbb</last>
</name>
<achievements>
<received>Award B</received>
</achievements>
</user>
</users><!--awards-->
<awards>
<award>
<name>Award A</name><!--here the list of the users who recieved this award has to be included-->
<user>
<name>
<first>abc</first>
<last>xyz</last>
</name>
</user>
<user>
<name>
<first>dsd</first>
<last>sdasdsadsa</last>
</name>
</user>
</award>
<award>
<name>Award B</name>
<user>
<name>
<first>abc</first>
<last>xyz</last>
</name>
</user>
<user>
<name>
<first>aaa</first>
<last>bbb</last>
</name>
</user>
</award>
</awards>
</document>
解释:正确使用 keys 并覆盖 identity rule 。
更新:OP已显示实际需要的输出格式。这与我猜测的非常接近。唯一的修改是使用此模板,在初始解决方案中输入一个:
<xsl:template match="user" mode="inclusion">
<user identity="{@identity}">
<xsl:copy-of select="concat(name/first, ' ', name/last)"/>
</user>
</xsl:template>