2017-10-15 8 views
0

は、私は次のようにXSLTを使用してレンダリングされるフォームのXMLテンプレートを持っている:XSLT名前値ペアの辞書を取り込むXMLフォーム入力は

の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ファイルに配列型変数を渡すことができません。

辞書をノードセットに変換し、それをargumentlistパラメータとして渡しますか?

他にも提案や回避策がありますか?あなたがXSLTで.NET辞書を表現したい場合は、私は、私はネットMVC

答えて

0

でこれを達成しようとしているXSL/XML

ノートでの作業素晴らしいじゃないとして、いくつかのコードスニペットは、あまりにも参考になりますSaxon 9.8 HE(NuGetとSourceforgeで利用可能)がサポートしているXSLT 3.0に移動したい場合は、convert itXPath 3.1 mapにすることができます。

次に、あなたのXSLTは(そう基本的にあなたがタイプmap(xs:string, xs:string)のパラメータを宣言して、あなたは、関数呼び出し$field-map(@name)であなたの@nameマップ/辞書のキーを渡す機能として使用することができます)

<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> 

ようになります。 。

A 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属性が設定されています。

+0

感謝を。私も同様のものを管理しました - 上記の私の答えを参照してください。 – adam78

1

私はマーティンHonnenの答えのようなものを管理するが、以下は3.0

をXSLTするために移動することなく、私がやったことですしました。私はxsltargumentを追加するとのXPathNodeIteratorに辞書を変換することにより、HTMLヘルパーを更新:私のXSLTで

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()); 

次のように私は更新:

<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> 

関連する問題