XSLT 模板不起作用
本文关键字:不起作用 XSLT | 更新日期: 2023-09-27 18:31:18
尽管在各种网站上阅读了大量有关XSLT模板的文档,但我无法使XSLT与我的C#代码一起使用。
这是我的工作 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();
}
谢谢!
语法
select="user"
表示"查找所有称为'用户'的子元素并应用其匹配模板"。没有"用户"元素,因此没有输出。
调用命名模板,或应用生成匹配项的选择。
例如,您可以:
<xsl:apply-templates select="ArrayOfUserModel/UserModel"/>
并更改模板以匹配用户模型:
<xsl:template match="UserModel">
尽量避免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 的常规列表布局(表格)和列表项将变得更加可读且更易于维护。
最有可能的是,在问题中未显示的 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>