对标题感到抱歉 - 不知道如何说出来。
基本上我有一些像这样的XML:
<countries>
<country handle="bangladesh"/>
<country handle="india"/>
<country handle="pakistan"/>
</countries>
这样的一些XSLT(不起作用):
<xsl:template match="/countries">
<xsl:param name="popular"/>
<xsl:apply-templates select="country[count($popular/country[@handle = current()/@handle]) > 0]" />
</xsl:template>
<xsl:template match="/countries/country">
…
</xsl:template>
我想传递一个像这样的热门目的地列表:
<popular>
<country handle="india"/>
<country handle="pakistan"/>
</popular>
...到/ countries模板,让它只对$ popular param中的那些进行操作。目前,这根本不起作用。将选择器更改为country [true()]对它们进行操作,所以至少我知道基本结构是正确的。
有什么想法吗?我想我可能会对目前的“当前()”感到困惑。
答案 0 :(得分:2)
此问题的解决方案简单明了(无需字符串编码或递归)。
此转化:
<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:param name="pPopular">
<country handle="india"/>
<country handle="pakistan"/>
</xsl:param>
<xsl:variable name="vPopular"
select="document('')/*/xsl:param[@name='pPopular']"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="country">
<xsl:if test="@handle = $vPopular/*/@handle">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<countries>
<country handle="bangladesh"/>
<country handle="india"/>
<country handle="pakistan"/>
</countries>
生成想要的正确结果:
<countries>
<country handle="india"/>
<country handle="pakistan"/>
</countries>
答案 1 :(得分:1)
这比你想象的要简单得多:
<xsl:template match="/">
<popular>
<xsl:copy-of select="/countries/country[@handle=$popular/country/@handle]"/>
</popular>
</xsl:template>
修改强>
上面简单地说明了OP的原始XPath查询有什么问题。这是一个完整的工作示例:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="popular"/>
<xsl:template match="/">
<xsl:apply-templates select="/countries">
<xsl:with-param name="popular" select="$popular"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="/countries">
<xsl:param name="popular"/>
<countries>
<xsl:apply-templates select="country[@handle=$popular/country/@handle]"/>
</countries>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
......以及一个叫它的程序:
static void Main(string[] arguments)
{
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("xsltfile1.xslt");
XmlDocument d = new XmlDocument();
d.LoadXml(@"
<popular>
<country handle='india'/>
<country handle='xxx'/>
</popular>");
XsltArgumentList args = new XsltArgumentList();
args.AddParam("popular", "", d.DocumentElement);
xslt.Transform("xmlfile1.xml", args, Console.Out);
Console.ReadKey();
}
答案 2 :(得分:0)
以下是使用递归模板的方法。您必须将热门目的地作为逗号分隔列表(例如:"'india,pakistan,'"
)
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/countries">
<xsl:param name="popular" select="'india,pakistan,'" />
<xsl:for-each select="country">
<xsl:call-template name="print-country-from-list">
<xsl:with-param name="pc" select="."/>
<xsl:with-param name="listc" select="$popular"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template match="/countries/country">
... <xsl:value-of select="@handle"/>
</xsl:template>
<xsl:template name="print-country-from-list">
<xsl:param name="pc"/>
<xsl:param name="listc" select="''"/>
<xsl:variable name="h" select="substring-before($listc, ',')"/>
<xsl:if test="$h">
<xsl:choose>
<xsl:when test="$pc/@handle=$h">
<xsl:apply-templates select="$pc" />
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="print-country-from-list">
<xsl:with-param name="pc" select="$pc"/>
<xsl:with-param name="listc" select="substring-after($listc, ',')"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
输出是2个国家。