样式化 xml 返回相同的 xml 文档,一种让代码工作的方法

Posted

技术标签:

【中文标题】样式化 xml 返回相同的 xml 文档,一种让代码工作的方法【英文标题】:styling xml returns same xml document, A way to get code to work 【发布时间】:2016-03-15 19:42:54 【问题描述】:
 SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ICDBConnectionString"].ConnectionString);
        conn.Open();

        string SQL = "Select TUReportData from TUReport WHERE ConsumerID = @ConsumerID";

        SqlCommand cmd = new SqlCommand(SQL, conn);
        cmd.Parameters.Add(new SqlParameter("@ConsumerID", txtIDNumber.Text));

        SqlDataAdapter adapter = new SqlDataAdapter(cmd);

        DataTable dt = new DataTable();
        adapter.Fill(dt);

        dt.TableName = "XMLData";
        dt.ToString();
        dt.WriteXml("C:/inetpub/wwwroot/TUWebServiceCaller/Log/temp.xml");

        // Getting file path    
        string strXSLTFile = Server.MapPath("styles/style.xslt");
        string strXMLFile = Server.MapPath("Log/temp.xml");

        // Creating XSLCompiled object    
        XslCompiledTransform objXSLTransform = new XslCompiledTransform();
        objXSLTransform.Load(strXSLTFile);

        // Creating StringBuilder object to hold html data and creates TextWriter object to hold data from XslCompiled.Transform method    
        StringBuilder htmlOutput = new StringBuilder();
        TextWriter htmlWriter = new StringWriter(htmlOutput);

        // Creating XmlReader object to read XML content    
        XmlReader reader = XmlReader.Create(strXMLFile);

        // Call Transform() method to create html string and write in TextWriter object.    
        objXSLTransform.Transform(reader, null, htmlWriter);
        Results.InnerHtml  = htmlOutput.ToString();

        // Closing xmlreader object    
        reader.Close();

运行时没有错误,但 XSLT 似乎没有对 XML 进行样式设置,因为它以与其传入的相同格式返回。整个 xml 应该重新格式化,并且我自己的整个页面版本与节点一起显示我已经指定到位了

XSLT 这就是 XSLT 示例

<xsl:for-each select="AddressNA08">
    <tr>
        <td>
            <xsl:value-of select="ConsumerNo"/>
        </td>
        <td>
            <xsl:value-of select="InformationDate"/>
        </td>
        <td>
            <xsl:value-of select="Line1"/>
        </td>
        <td>
            <xsl:value-of select="Line2"/>
        </td>
        <td>
            <xsl:value-of select="Suburb"/>
        </td>
        <td>
            <xsl:value-of select="City"/>
        </td>
        <td>
            <xsl:value-of select="PostalCode"/>
        </td>
        <td>
            <xsl:value-of select="ProvinceCode"/>
        </td>
        <td>
            <xsl:value-of select="Province"/>
        </td>
        <td>
            <xsl:value-of select="AddressPeriod"/>
        </td>
        <td>
            <xsl:value-of select="OwnerTenant"/>
        </td>
        <td>
            <xsl:value-of select="AddressChanged"/>
        </td>
    </tr>
</xsl:for-each>

XML

<AddressNA08>
    <ConsumerNo>645511310</ConsumerNo>
    <InformationDate>20090227</InformationDate>
    <Line1>8 HAAKBOS ST</Line1>
    <Line2 />
    <Suburb>ONVERWACHT</Suburb>
    <City>ELLISRAS</City>
    <PostalCode>0557</PostalCode>
    <ProvinceCode>
        NP
    </ProvinceCode>
    <Province>LIMPOPO</Province>
    <AddressPeriod>
        06
    </AddressPeriod>
    <OwnerTenant>O</OwnerTenant>
    <AddressChanged>N</AddressChanged>
</AddressNA08>

这些是我正在使用的所有文件

【问题讨论】:

如果这是一个 XSLT 问题,请显示输入 XML 文档的示例并显示 style.xslt 样式表。 这里可以附加文件吗 Xml 示例 645511310200902278 HAAKBOS STONVERWACHTELLISRAS0557NPLIMPOPO06ON 不,这里不可能附加文件。并且请不要链接到场外资源。将您的示例 XML 和 XSLT 样式表缩减为 minimal, complete and verifiable example 并将它们编辑到您的问题中。 您好,我很好奇...我的回答对您解决问题有帮助吗? 【参考方案1】:

使用这样的方法,我通过 xslt 将 xml 转换为 xhtml:

   public static XmlDocument TransformToHtml(XmlDocument XmlDoc, XmlDocument XSLT) 

        var bArr = new System.Text.UTF8Encoding().GetBytes(XmlDoc.InnerXml);
        MemoryStream m = new MemoryStream(bArr);
        System.Xml.XPath.XPathDocument xDoc;
        XmlReaderSettings xrs = new XmlReaderSettings();
        xrs.CheckCharacters = false;
        using (XmlReader xr = XmlReader.Create(m, xrs)) 
            xDoc = new System.Xml.XPath.XPathDocument(xr);
        

        StringBuilder resultString = new StringBuilder();
        var ws = new XmlWriterSettings();
        ws.CheckCharacters = false;
        ws.Indent = true;
        ws.OmitXmlDeclaration = true;
        XmlWriter writer = XmlWriter.Create(resultString, ws);
        var sets = new XsltSettings(true, true);

        string transformedXHTML = null;
        XslCompiledTransform transform = new XslCompiledTransform(false);
        transform.Load(XSLT, sets, null);
        transform.Transform(xDoc, writer);
        transformedXHTML = resultString.ToString();
        var doc = new XmlDocument();
        doc.LoadXml(transformedXHTML);
        return doc;
    

你这样称呼它(注意,缩短你的 xslt!):

        var xml = new XmlDocument();
        xml.LoadXml("<AddressNA08><ConsumerNo>645511310</ConsumerNo><InformationDate>20090227</InformationDate><Line1>8 HAAKBOS ST</Line1><Line2 />"
                   + "<Suburb>ONVERWACHT</Suburb><City>ELLISRAS</City><PostalCode>0557</PostalCode><ProvinceCode>NP</ProvinceCode><Province>LIMPOPO</Province>"
                   + "<AddressPeriod>06</AddressPeriod><OwnerTenant>O</OwnerTenant><AddressChanged>N</AddressChanged></AddressNA08>");

        var xslt = new XmlDocument();
        xslt.LoadXml("<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns='http://www.w3.org/1999/xhtml' version='1.0'>" +
                     "<xsl:output encoding='UTF-8' indent='yes' method='xml' standalone='no' omit-xml-declaration='no'/><xsl:template match='/'><xsl:for-each select='AddressNA08'>" +
                     "<tr><td><xsl:value-of select='ConsumerNo'/></td><td><xsl:value-of select='InformationDate'/></td><td><xsl:value-of select='Line1'/></td>" +
                     "<td><xsl:value-of select='Line2'/></td><td><xsl:value-of select='Suburb'/></td></tr></xsl:for-each></xsl:template></xsl:stylesheet>");
        var reslt = TransformToHtml(xml, xslt);

【讨论】:

在显示结果时将其发布到新页面的最佳方式是什么? @Tumelo,感谢您的支持和接受!在这里我不明白你的意思...如果你想通过 XSL 转换将你的 XML 转换为 HTML,你可以按照上面的方法来做。如果您的 XSLT 生成有效的 HTML(易于测试:只需将转换后的 XML(使用 doc.InnerXML)粘贴到一个新的文本文件中,将其命名为 test.html 并用您的浏览器打开它),显示它应该没有问题一个“新页面”。希望这会有所帮助...【参考方案2】:

您显示的 XML 文档和样式表 执行 生成的输出与输入文档不同,因此这不是错误的原因。我仍然想添加一个答案,因为您的 XSLT 样式表肯定需要改进,我认为这是您的问题的一部分。

如果您要输出所有元素名称和td 元素,为什么要写出它们,即使它们在输入中出现的顺序也是如此?

样式表

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" encoding="UTF-8" indent="yes" />

    <xsl:strip-space elements="*"/>

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

    <xsl:template match="AddressNA08">
        <tr>
            <xsl:apply-templates/>
        </tr>
    </xsl:template>

    <xsl:template match="*">
        <td>
            <xsl:apply-templates/>
        </td>
    </xsl:template>

</xsl:transform>

HTML 结果

<html>
   <tr>
      <td>645511310</td>
      <td>20090227</td>
      <td>8 HAAKBOS ST</td>
      <td></td>
      <td>ONVERWACHT</td>
      <td>ELLISRAS</td>
      <td>0557</td>
      <td>
         NP

      </td>
      <td>LIMPOPO</td>
      <td>
         06

      </td>
      <td>O</td>
      <td>N</td>
   </tr>
</html>

在线尝试此解决方案here。


我将省略实时项目中的一些标签。或者当我使用你的方式时选择排除哪些方式?

是的,添加一个额外的模板,您可以在其中列出不应出现在输出中的元素的名称。这是一个例子:

<xsl:template match="City | PostalCode"/>

还有here is the updated online version。

【讨论】:

你说得对,xslt 可以改进。并感谢您提供指向“XSLT-Fiddle”的链接,我不知道... +1 从我这边获取此信息(即使您的答案没有回答问题:-)) @Mathias Muller,我将省略实时项目中的一些标签。或者当我使用你的方式时选择排除哪些方式? @Mathias,这里有一些指导link 无论我如何尝试调用节点,他们似乎都无法使用 xsl @Tumelo 那是因为您的输入文档中有命名空间(您没有向我们展示)。我们对 *** 制定了一项政策,即不一遍又一遍地扩展和更改问题。因此,如果您需要有关尚未向我们展示的新文档的帮助,请提出一个新问题。与 XSLT 问题一样,在新问题中您需要提及以下内容:完整输入文档、您当前的 XSLT 代码和您期望的输出。

以上是关于样式化 xml 返回相同的 xml 文档,一种让代码工作的方法的主要内容,如果未能解决你的问题,请参考以下文章

从 CLOB 列中过滤非 XML 数据

[XML]学习笔记XSLT

可以将 XSLT 样式表添加到序列化的 XML 文档吗?

文档对象模型操作xml文档

DOM

怎么将XML转换成HTML文件