如何在XSLT中解析C#传递的参数以过滤XML输出?
如何在XSLT中解析C#传递的参数来过滤XML
嘿,这个需求我刚好实操过,用C#的XslCompiledTransform传参数搭配XSLT过滤完全能搞定,我结合你的汽车列表例子,拆解成C#传参和XSLT接收过滤两部分来讲,一目了然。
第一步:C#代码中传递参数给XSLT
首先你需要用XsltArgumentList来封装要传递的过滤参数,然后传给XslCompiledTransform.Transform方法。比如我们要过滤指定品牌和型号的汽车,代码示例如下:
using System; using System.Xml; using System.Xml.Xsl; class CarFilterProgram { static void Main() { // 初始化XSLT转换器并加载你的XSLT文件 var transform = new XslCompiledTransform(); transform.Load("CarFilter.xslt"); // 创建参数列表,添加过滤条件参数 var xsltArgs = new XsltArgumentList(); // 传递目标品牌:比如只保留Audi xsltArgs.AddParam("targetBrand", "", "Audi"); // 可选:传递目标型号,比如只保留A6(空字符串表示不过滤型号) xsltArgs.AddParam("targetModel", "", "A6"); // 执行转换,输出过滤后的XML文件 using (var outputWriter = XmlWriter.Create("FilteredCars.xml")) { transform.Transform("OriginalCars.xml", xsltArgs, outputWriter); } } }
第二步:XSLT中接收参数并过滤XML
接下来在XSLT文件里,你需要用<xsl:param>声明从C#传递过来的参数,然后通过参数值来过滤节点。以下是适配你汽车列表的XSLT示例:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 声明从C#传入的参数,名字要和C#里AddParam的第一个参数完全一致 --> <xsl:param name="targetBrand" /> <!-- 给型号参数设置默认值为空字符串,避免未传参时出错 --> <xsl:param name="targetModel" select="''" /> <!-- 匹配根节点,输出外层的<cars>容器 --> <xsl:template match="/"> <cars> <!-- 只对符合过滤条件的<car>节点应用模板 --> <xsl:apply-templates select="cars/car[@brand = $targetBrand]" /> </cars> </xsl:template> <!-- 匹配<car>节点,进一步过滤型号(如果有传型号参数) --> <xsl:template match="car"> <xsl:if test="$targetModel = '' or @model = $targetModel"> <!-- 复制符合条件的<car>节点及其所有属性 --> <xsl:copy-of select="." /> </xsl:if> </xsl:template> </xsl:stylesheet>
关键细节说明
- 参数引用:在XSLT里用
$参数名来引用C#传递的参数,比如$targetBrand,注意参数名要完全匹配,大小写敏感哦。 - 条件过滤:我这里用了两层过滤:先在
<xsl:apply-templates>的select属性里过滤品牌,再在模板里用<xsl:if>判断型号,你也可以把条件合并成一个test表达式,比如@brand = $targetBrand and ($targetModel = '' or @model = $targetModel)。 - 参数默认值:给
targetModel设置了select="''"的默认值,这样如果C#里不传这个参数,XSLT就会忽略型号过滤,直接输出所有目标品牌的汽车。 - 参数类型:如果传递的是数值、布尔值等非字符串类型,C#里直接传对应类型即可,XSLT会自动识别,比如传递价格上限:
xsltArgs.AddParam("maxPrice", "", 35000),然后在XSLT里用@price <= $maxPrice判断。
内容的提问来源于stack exchange,提问作者Guillaume D.




