2

さまざまな Web サイトで XSLT テンプレートに関するドキュメントをたくさん読んだにもかかわらず、自分の C# コードで 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();
    }

どうもありがとうございます !

4

3 に答える 3

3

構文

select="user"

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

名前付きテンプレートを呼び出すか、一致を生成する選択を適用します。

たとえば、for-each の代わりに、次のことができます。

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

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

<xsl:template match="UserModel">

   

于 2012-04-14T15:26:50.103 に答える
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 が読みやすくなり、保守が容易になることに注意してください。

于 2012-04-14T15:35:37.570 に答える
1

おそらく、質問に表示されていない XML ドキュメントで は、childUserModelの要素に child がArrayOfUserModeluser含まれていません。

これがこの行の理由です:

<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>
于 2012-04-14T15:45:59.317 に答える