Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将XhtmlTextWriter与XmlTextReader一起使用_C#_.net_Linq_Parsing_Xmltextreader - Fatal编程技术网

C# 将XhtmlTextWriter与XmlTextReader一起使用

C# 将XhtmlTextWriter与XmlTextReader一起使用,c#,.net,linq,parsing,xmltextreader,C#,.net,Linq,Parsing,Xmltextreader,阅读之后,我决定用XmlReader更新以下代码(使用XmlDocument): 渲染控件 public string Rendering(Control baseControl) { StringBuilder stringBuilder = new StringBuilder(); using (StringWriter stringWriter = new StringWriter(stringBuilder)) using (XhtmlTextWriter ht

阅读之后,我决定用
XmlReader
更新以下代码(使用
XmlDocument
):

渲染控件

public string Rendering(Control baseControl)
{
    StringBuilder stringBuilder = new StringBuilder();

    using (StringWriter stringWriter = new StringWriter(stringBuilder))
    using (XhtmlTextWriter htmlWriter = new XhtmlTextWriter(stringWriter))
    {
        baseControl.RenderControl(htmlWriter);

        return PretifyWithNewlines(stringBuilder.ToString());
    }
}
在每个节点后添加换行符

private string PretifyWithNewlines(string minifiedMarkup)
{   
    XmlDocument xmlDocument = new XmlDocument();
    xmlDocument.XmlResolver = null;

    try
    {
        xmlDocument.LoadXml("<base>" + minifiedMarkup + "</base>");
    }
    catch // when minifiedMarkup contains the whole HTML with DTD tag defined, 
    {                                    // it throws an exception with <base>
        xmlDocument.LoadXml(minifiedMarkup);
    }

    return recursiveOperation(xmlDocument.ChildNodes)
           .Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine)
           .Replace(Environment.NewLine + "<base>" + Environment.NewLine, "")
           .Replace(Environment.NewLine + "</base>" + Environment.NewLine, "");

}
问题:
  • 是否存在优化现有代码的空间

  • 如何从
    Control
    StringWriter
    xhtmltextwitter
    对象直接实例化
    XmlTextReader
    ?或者我真的需要先将其呈现为
    字符串
    ,然后实例化
    XmlTextReader

编辑 根据Jon Skeet的回答,这里是更新。其思想是在每个元素后内爆一个换行符:

美化前:

<div class="tag"><span>text<span class="another-span"></span></span></div><div>Text<img src="some/relative/URL/" />namely</div>
 <div class="tag">
 <span>
 text
 <span class="another-span"></span>
 </span>
 </div>
 <div>
 Text
 <img src="some/relative/URL/" />
 namely
 </div>
text
修饰后:

<div class="tag"><span>text<span class="another-span"></span></span></div><div>Text<img src="some/relative/URL/" />namely</div>
 <div class="tag">
 <span>
 text
 <span class="another-span"></span>
 </span>
 </div>
 <div>
 Text
 <img src="some/relative/URL/" />
 namely
 </div>

文本
正文
即
请注意
span。另一个span
保持折叠,而其他所有内容(包含子节点)都展开。缩进将由Visual Studio断言

是否存在优化现有代码的空间

当然。我要更改的第一个地方与如何加载XML无关——它是字符串连接。我要将您的
递归操作
方法更改为:

private static string RecursiveOperation(XmlNodeList xmlNodeList)
{
    StringBuilder result = new StringBuilder();

    foreach (XmlNode currentNode in xmlNodeList)
    {
        XmlNode clonedNode = currentNode;

        // Remove try/finally block - if an exception is thrown your
        // result will be lost anyway
        string interimMarkup = RecursiveOperation(currentNode.ChildNodes);
        clonedNode.InnerXml = interimMarkup;
        result.Append(Environment.NewLine)
              .Append(clonedNode.OuterXml)
              .Append(Environment.NewLine);
    }
    return result.ToString();
}
您可以使用传递到
RecursiveOperation
中的单个
StringBuilder
进一步优化它,但我还没有完全掌握您的代码。(在早上第一杯咖啡之前。)

就XML处理本身而言,您目前正在通过在每个子节点中设置
OuterXml
节点(递归)来进行大量的重新分析。我想如果我能更好地理解你在做什么,那么改变整个方法是可行的。考虑到这是
XmlReader
真正没有的功能(这没有意义),目前还不清楚您是否应该注意另一篇文章

如何从控件、StringWriter或XhtmlTextWriter对象直接实例化XmlTextReader?或者我真的需要先将其呈现为字符串,然后实例化XmlTextReader吗

从这些对象中创建
XmlTextReader
究竟意味着什么还不清楚——它们本身并不是XML数据的来源。我觉得你的东西对我来说已经很合理了


如果您仍然担心性能,那么应该避免猜测,并使用探查器来测量所花费的时间。不过,您应该先为自己设定一个目标,否则您将不知道何时完成优化。

您这样做纯粹是出于性能原因吗?您是否有证据表明加载XML实际上是缓慢的一部分?我要做的第一件事是用
StringBuilder
(传递到
recursiveOperation
,所以只有一个)替换字符串连接。@JonSkeet,是的,性能是这里最主要的问题。正如文章中提到的,
XmlTextReader
linqtoxml
是赢家。我认为
XmlDocument
的速度很慢,而且有点贬值。那么您是否已经有了这方面的基准测试工具,以便可以衡量您的性能?如果没有,那么在开始更改代码之前,首先要做的就是这样做
XmlDocument
当然没有被弃用,尽管除非我不得不这样做,否则我不会在新代码中使用它。我怀疑你的很多时间实际上都会花在重新分析上(当你设置
InnerXml
属性时)。@安妮:那么你已经有了哪些性能测试?您是否能够对这些改进进行基准测试?目前,我只是在单元测试用例中进行压力测试。类似于使用随机参数调用控件生成器来构建控件对象,然后呈现控件以生成标记字符串。在构建控件时,某些上下文是未知的,这会阻止我巧妙地种植换行符。这就是为什么我要做这个后处理。与其随机做这个,不如找一个真实的测试用例,计算出你需要它们的速度,然后进行测试。然后你就会知道你离满足你的要求有多近了。Jon,我已经注意到了你的观点,在这一点上,我想我需要等待用户的反馈。除非存在重大的性能问题,否则当前的方法是可行的。OAN,您在前面的评论中暗示,
XmlDocument
将不是您在新代码中的选择。我想知道,你会用什么来代替
Linq到XML
XmlTextReader
?如果我删除try/catch,它会失败一些测试。我必须检查每个节点的条件
cloneNode.NodeType==XmlNodeType.Text
,然后
继续
以避免此错误:
无法为当前节点设置“InnerXml”,因为它是只读的或不能有子节点。
。从面向对象设计的角度来看,我认为try-catch是比if-else更好的构造。