我有一个表单的xml模板,使用xslt进行渲染,如下所示:
的xml:
<form-template>
<fields>
<field type="text" required="true" label="Subject" class="form-control" name="subject" subtype="text"></field>
<field type="textarea" required="true" label="Description" class="form-control" name="description" subtype="textarea" rows="3"></field>
</fields>
</form-template>
的xsl:
<xsl:template match="/*">
<xsl:for-each select="fields/field">
<xsl:if test="@type='text'">
<label for="{@name}"><xsl:value-of select="@label"/></label>
<input class="form-control" data-val="{@required}" data-val-required="The {@label} field is required." id="{@name}" name="{@name}" type="text" value=""></input>
<span class="field-validation-valid" data-valmsg-for="{@name}" data-valmsg-replace="true"></span>
</xsl:if>
</xsl:for-each>
</xsl:template>
使用自定义HTMLHelper呈现表单。
@Html.RenderXml(Model.Template, Server.MapPath("~/Content/form.xslt"))
值存储为名称/值对:
var values = new Dictionary<string, string> {{"subject", "This is the subject"}, {"description", "This is the description"}};
如何将这些值传递给xsl并对xml模板中的每个表单字段进行迭代,如果名称与字段名称匹配,则使用该值填充相应的字段。
我已经搜索了但我无法看到如何将数组类型变量传递给xsl文件。
我是否将字典转换为节点集并将其作为参数列表参数传递?
有没有人有任何其他建议或解决方法。一些代码片段也会有所帮助,因为我不能很好地使用xsl / xml
注意我试图在.Net MVC
中实现这一点答案 0 :(得分:1)
我管理过类似于Martin Honnen的回答,但没有转向xslt 3.0
以下是我的所作所为。我通过添加xsltargument并将字典转换为XPathNodeIterator来更新HTML帮助器:
var args = new XsltArgumentList();
var dict = new Dictionary<string, string> {{ "subject", "This is the subject" }, { "description", "This is the description" }};
var el = new XElement("keyvalues", dict.Select(kv => new XElement("keyvalue", new XAttribute("key", kv.Key), new XAttribute("value", kv.Value))));
args.AddParam("keyvalues", "", el.CreateNavigator());
在我的xslt中,我更新如下:
<xsl:param name="keyvalues"/>
<xsl:template match="/*">
<xsl:for-each select="fields/field">
<xsl:if test="@type='text'">
<label for="{@name}"><xsl:value-of select="@label"/></label>
<input class="form-control" data-val="{@required}" data-val-required="The {@label} field is required." id="{@name}" name="{@name}" type="text" value="{$keyvalues/keyvalue[@key = current()/@name]/@value}"></input>
<span class="field-validation-valid" data-valmsg-for="{@name}" data-valmsg-replace="true"></span>
</xsl:if>
</xsl:for-each>
答案 1 :(得分:0)
如果你想在XSLT中表示一个.NET字典,那么你可能希望移动到Saxon 9.8 HE(在XSLT 3.0和Sourceforge上可用)支持的NuGet,你可以{{3}进入convert it。
然后你的XSLT看起来像
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"
>
<xsl:param name="field-map" as="map(xs:string, xs:string)" required="yes"/>
<xsl:output method="html" indent="yes"/>
<xsl:template match="/*">
<xsl:for-each select="fields/field">
<xsl:if test="@type='text'">
<label for="{@name}">
<xsl:value-of select="@label"/>
</label>
<input class="form-control" data-val="{@required}" data-val-required="The {@label} field is required." id="{@name}" name="{@name}" type="text" value="{$field-map(@name)}"></input>
<span class="field-validation-valid" data-valmsg-for="{@name}" data-valmsg-replace="true"></span>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
(所以基本上你声明了map(xs:string, xs:string)
类型的参数,然后你可以将它用作函数调用@name
中传递$field-map(@name)
map / dictionary键的函数。 / p>
运行上面的C#片段,传入字典并写出带有转换结果的字符串
var values = new Dictionary<string, string> { { "subject", "This is the subject" }, { "description", "This is the description" } };
XdmMap mapParam = XdmMap.MakeMap(values);
Processor proc = new Processor();
Uri baseUri = new Uri(new FileInfo(".").FullName);
XmlResolver resolver = new XmlUrlResolver();
Xslt30Transformer transformer = proc.NewXsltCompiler().Compile(resolver.ResolveUri(baseUri, "sheet1.xslt")).Load30();
transformer.SetStylesheetParameters(new Dictionary<QName, XdmValue> { { new QName("field-map"), mapParam } });
Serializer serializer = proc.NewSerializer();
using (StringWriter sw = new StringWriter())
{
serializer.SetOutputWriter(sw);
using (FileStream fs = File.OpenRead(@"template1.xml"))
{
transformer.ApplyTemplates(fs, serializer);
}
Console.WriteLine(sw.ToString());
}
我得到的输出是例如
<label for="subject">Subject</label><input class="form-control" data-val="true" data-val-required="The Subject field is required." id="subject" name="subject" type="text" value="This is the subject"><span class="field-validation-valid" data-valmsg-for="subject" data-valmsg-replace="true"></span>
因此已设置value
属性。