2012-04-14 8 views
2

XSLTテンプレートに関するさまざまなWebサイトのドキュメントをたくさん読んでいても、C#コードでXSLTを動作させることはできません。ここでXSLTテンプレートが動作しない

は私の作業XSLTファイルである:ここで

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:template match="/"> 
<HTML> 
<BODY> 
    <TABLE BORDER="2"> 
    <TR> 
     <TD>First name</TD> 
     <TD>Last name</TD> 
     <TD>Age</TD> 
    </TR> 

    <xsl:for-each select="ArrayOfUserModel/UserModel"> 
      <TR> 
       <TD><xsl:value-of select="FirstName"/></TD> 
       <TD><xsl:value-of select="LastName"/></TD> 
       <TD><xsl:value-of select="Age"/></TD> 
       </TR> 
    </xsl:for-each> 

    </TABLE> 
</BODY> 
</HTML> 
</xsl:template> 
</xsl:stylesheet> 

は私の非作業XSLTファイル(および処理は理論的には同じことを返すのではなくすべきスタイルシートの末尾にテンプレートに移動されましたです)任意のユーザ情報を表示します。ここでは

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:template match="/"> 
    <HTML> 
<BODY> 
    <TABLE BORDER="2"> 
    <TR> 
     <TD>First name</TD> 
     <TD>Last name</TD> 
     <TD>Age</TD> 
    </TR> 

    <xsl:for-each select="ArrayOfUserModel/UserModel"> 
      <xsl:apply-templates select="user"/> 
    </xsl:for-each> 

    </TABLE> 
</BODY> 
    </HTML> 
</xsl:template> 


<xsl:template match="user"> 
    <TR> 
<TD><xsl:value-of select="FirstName"/></TD> 
<TD><xsl:value-of select="LastName"/></TD> 
<TD><xsl:value-of select="Age"/></TD> 
    </TR> 
</xsl:template> 
</xsl:stylesheet> 

私はXSLT変換に使用するC#コード: (私はいくつかのプロパティを含む直列化可能UserModelオブジェクト、およびXSLTファイルの内容を渡し、それはHTMLを返します)

public static string TransformXml2(object data, string xslt) 
    { 
     XmlSerializer xs = new XmlSerializer(data.GetType()); 
     string xml; 
     using (StringWriter swr = new StringWriter()) 
     { 
      xs.Serialize(swr, data); 
      xml = swr.ToString(); 
     } 

     // Simple data checks 
     if (string.IsNullOrEmpty(xml)) 
     { 
      throw new ArgumentException("Param cannot be null or empty", "xml"); 
     } 
     if (string.IsNullOrEmpty(xslt)) 
     { 
      throw new ArgumentException("Param cannot be null or empty", "xslt"); 
     } 

     // Create required readers for working with xml and xslt 
     StringReader xsltInput = new StringReader(xslt); 
     StringReader xmlInput = new StringReader(xml); 
     XmlTextReader xsltReader = new XmlTextReader(xsltInput); 
     XmlTextReader xmlReader = new XmlTextReader(xmlInput); 

     // Create required writer for output 
     StringWriter stringWriter = new StringWriter(); 
     XmlTextWriter transformedXml = new XmlTextWriter(stringWriter); 

     // Create a XslCompiledTransform to perform transformation 
     XslCompiledTransform xsltTransform = new XslCompiledTransform(); 

     try 
     { 
      xsltTransform.Load(xsltReader, new XsltSettings(true, true), null); 
      xsltTransform.Transform(xmlReader, transformedXml); 
     } 
     catch (XmlException xmlEx) 
     { 
      // TODO : log - "Could not load XSL transform: \n\n" + xmlEx.Message 
      throw; 
     } 
     catch (XsltException xsltEx) 
     { 
      // TODO : log - "Could not process the XSL: \n\n" + xsltEx.Message + "\nOn line " + xsltEx.LineNumber + " @ " + xsltEx.LinePosition) 
      throw; 
     } 
     catch (Exception ex) 
     { 
      // TODO : log 
      throw; 
     } 

     return stringWriter.ToString(); 
    } 

ありがとうございます!

答えて

3

構文

select="user" 

は「『ユーザー』と呼ばれ、すべての子要素を検索し、その一致したテンプレートを適用する」を意味します。 「user」要素がないため、出力はありません。

名前付きテンプレートを呼び出すか、一致する選択を適用します。たとえば、代わりのために、それぞれの

、あなたはできます

<xsl:apply-templates select="ArrayOfUserModel/UserModel"/> 

そしてUserModelに一致するようにテンプレートを変更します。

<xsl:template match="UserModel"> 

+0

おかげでマルクGravell、。 – virrea

+0

私はusermodel.xslファイルをメインのXSLファイルと同じローカルフォルダにあるを使用しようとしていますが、VC#は次のように言います。フランス語で禁止されています。無関係な質問のように聞こえる@virrea ... – virrea

+1

...? –

2

for-eachを避けて試してみて、テンプレートのために行きます使用方法:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:template match="/"> 
     <HTML> 
      <BODY> 
       <xsl:apply-templates /> 
      </BODY> 
     </HTML> 
    </xsl:template> 

    <xsl:template match="ArrayOfUserModel"> 
     <TABLE BORDER="2"> 
      <TR> 
       <TD>First name</TD> 
       <TD>Last name</TD> 
       <TD>Age</TD> 
      </TR> 
      <xsl:apply-templates /> 
     </TABLE> 
    </xsl:template> 

    <xsl:template match="UserModel"> 
     <TR> 
      <TD><xsl:value-of select="./FirstName" /></TD> 
      <TD><xsl:value-of select="./LastName" /></TD> 
      <TD><xsl:value-of select="./Age" /></TD> 
     </TR> 
    </xsl:template> 

</xsl:stylesheet> 

ドキュメント本文、一般的なリストレイアウト(テーブル)、およびリスト項目に関する出力の部分を分割することにより、xsltは読みやすくなり、維持しやすくなります。

+0

Filburtに感謝します。 – virrea

1

はおそらく、質問には示されていないXML文書で、ArrayOfUserModelの子である何UserModel要素はuserを持っていません。

<xsl:apply-templates select="user"/> 

任意のuserの要素を見つけることができないので、何のテンプレートが適用されません取得:この行は、なぜ

です。

ソリューション

置き換え

<xsl:for-each select="ArrayOfUserModel/UserModel">     
    <xsl:apply-templates select="user"/>   
</xsl:for-each> 

と:

<xsl:apply-templates select="ArrayOfUserModel/UserModel"/> 

と変更

<xsl:template match="user"> 

へ:

<xsl:template match="UserModel"> 

完全なコードになる:魔法のように動作

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="/"> 
     <HTML> 
    <BODY> 
     <TABLE BORDER="2"> 
     <TR> 
      <TD>First name</TD> 
      <TD>Last name</TD> 
      <TD>Age</TD> 
     </TR> 

     <xsl:apply-templates select="ArrayOfUserModel/UserModel"/> 

     </TABLE> 
    </BODY> 
     </HTML> 
    </xsl:template> 


    <xsl:template match="UserModel"> 
     <TR> 
    <TD><xsl:value-of select="FirstName"/></TD> 
    <TD><xsl:value-of select="LastName"/></TD> 
    <TD><xsl:value-of select="Age"/></TD> 
     </TR> 
</xsl:stylesheet> 
+0

@virrea:どうぞよろしくお願いいたします。 –

関連する問題