Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.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# XMLWriterTraceListener生成文本墙,而不是格式化的XML_C#_Xml_Logging_Tracelistener - Fatal编程技术网

C# XMLWriterTraceListener生成文本墙,而不是格式化的XML

C# XMLWriterTraceListener生成文本墙,而不是格式化的XML,c#,xml,logging,tracelistener,C#,Xml,Logging,Tracelistener,我在跟踪侦听器中添加了一个对象,如下所示 System.Diagnostics.XmlWriterTraceListener xmlTrace = new System.Diagnostics.XmlWriterTraceListener("Trace.xml"); xmlTrace.IndentLevel = 1; xmlTrace.IndentSize = 4; System.Diagnostics.Trace.Listeners.Add(xmlTrace); 并且它正在成功地

我在跟踪侦听器中添加了一个对象,如下所示

System.Diagnostics.XmlWriterTraceListener xmlTrace = new 
    System.Diagnostics.XmlWriterTraceListener("Trace.xml");
xmlTrace.IndentLevel = 1;
xmlTrace.IndentSize = 4;

System.Diagnostics.Trace.Listeners.Add(xmlTrace);
并且它正在成功地接收来自Trace.WriteLine()、Trace.TraceInformation()等的消息。唯一的问题是,它正在写入的Trace.xml文件不包含换行或缩进,因此从人的角度看是不可读的。我是否遗漏了一个中间步骤(XMLStreamWriter?),该步骤将优化输出

当前输出为:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent"><System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system"><EventID>0</EventID><Type>3</Type><SubType Name="Information">0</SubType><Level>8</Level><TimeCreated SystemTime="2014-03-20T18:05:43.2778822Z" /><Source Name="Program.vshost.exe" /><Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" /><Execution ProcessName="Program.vshost" ProcessID="6840" ThreadID="9" /><Channel/><Computer>ODYSSEY</Computer></System><ApplicationData>Startup!</ApplicationData></E2ETraceEvent>
0308Odyssey启动!
但我想这样写:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
    <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
        <EventID>0</EventID>
        <Type>3</Type>
        <SubType Name="Information">0</SubType>
        <Level>8</Level>
        <TimeCreated SystemTime="2014-03-20T18:05:43.2778822Z" />
        <Source Name="Program.vshost.exe" />
        <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />
        <Execution ProcessName="Program.vshost" ProcessID="6840" ThreadID="9" />
        <Channel/>
        <Computer>ODYSSEY</Computer>
    </System>
    <ApplicationData>Startup!</ApplicationData>
</E2ETraceEvent>

0
3.
0
8.
艰苦的跋涉
启动!

看起来没有任何方法可以做到这一点,即使是反射:

如果您可以在mono版本中获得xml编写器设置,则可以:

您可以使用服务跟踪查看器打开XML跟踪:


否则,请复制并粘贴到您最喜欢的IDE或XML编辑器。

有点晚,但如果您想在代码中执行此操作,下面的链接将很好地展示如何读取XML。您可以读取子树,然后可能将其反序列化到类中。然后使用适当的设置将其序列化回XML

我还从E2ETraceEvent Xml节点创建了C#类,以便对Xml片段进行反序列化

示例代码:

using (var fileStream = new FileStream(logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (XmlReader reader = new XmlTextReader(fileStream, XmlNodeType.Element, null))
{
    while (reader.Read())
    {
        if (reader.Name == "E2ETraceEvent" && reader.NodeType == XmlNodeType.Element)
        {
            using (XmlReader subReader = reader.ReadSubtree())
            {
                while (subReader.Read())
                {
                    var elementString = subReader.ReadOuterXml();
                    if (!string.IsNullOrWhiteSpace(elementString))
                    {
                        using (var xStream = this.GenerateStreamFromString(elementString))
                        {
                            XElement traceElement = XElement.Load(xStream);
                            var serializer = new XmlSerializer(typeof(E2ETraceEvent));
                            var traceObject = (E2ETraceEvent)serializer.Deserialize(traceElement.CreateReader());

                            var formattedXml = this.SerializeToXmlString<E2ETraceEvent>(traceObject); 
                        }
                    }
                }
            }
        }
    }
}
====================================

private Stream GenerateStreamFromString(string s)
{
    var stream = new MemoryStream();
    var writer = new StreamWriter(stream);
    writer.Write(s);
    writer.Flush();
    stream.Position = 0;
    return stream;
}
=====================================

private string SerializeToXmlString<T>(T objectToSerialize)
{
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
    var settings = new XmlWriterSettings
    {
        Indent = true,
        OmitXmlDeclaration = true
    };
    var xml = string.Empty;

    using (var sw = new StringWriter())
    {
        using (XmlWriter writer = XmlWriter.Create(sw, settings))
        {
            xmlSerializer.Serialize(writer, objectToSerialize);
            xml = sw.ToString();
        }
    }

    return xml;
}
======================================
使用(var fileStream=newfilestream(logFilePath,FileMode.Open,FileAccess.Read,FileShare.ReadWrite))
使用(XmlReader=newxmlTextReader(fileStream,XmlNodeType.Element,null))
{
while(reader.Read())
{
if(reader.Name==“E2ETraceEvent”&&reader.NodeType==XmlNodeType.Element)
{
使用(XmlReader subReader=reader.ReadSubtree())
{
while(subReader.Read())
{
var elementString=subReader.ReadOuterXml();
如果(!string.IsNullOrWhiteSpace(elementString))
{
使用(var xStream=this.GenerateStreamFromString(elementString))
{
XElement traceElement=XElement.Load(xStream);
var serializer=新的XmlSerializer(typeof(E2ETraceEvent));
var traceObject=(E2ETraceEvent)序列化程序。反序列化(traceElement.CreateReader());
var formattedXml=this.SerializeToXmlString(traceObject);
}
}
}
}
}
}
}
====================================
私有流生成器StreamFromString(字符串s)
{
var stream=newmemoryStream();
var writer=新的StreamWriter(流);
作者:写;
writer.Flush();
流位置=0;
回流;
}
=====================================
私有字符串SerializeToXmlString(T objectToSerialize)
{
XmlSerializer XmlSerializer=新的XmlSerializer(typeof(T));
var设置=新的XmlWriterSettings
{
缩进=真,
OmitXmlDeclaration=true
};
var xml=string.Empty;
使用(var sw=new StringWriter())
{
使用(XmlWriter=XmlWriter.Create(软件,设置))
{
Serialize(writer,objectToSerialize);
xml=sw.ToString();
}
}
返回xml;
}
======================================

希望这有帮助

您可以使用服务跟踪查看器工具(SvcTraceViewer.exe)读取System.Diagnostics.XmlWriterTraceListener的输出

它应该是Windows SDK()的一部分

可以在Microsoft SDK目录下找到。例如:

C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\SvcTraceViewer.exe

我很感激,但我不会接受这个答案,因为我对XmlWriterTraceListener对象的IndentSize和IndentLevel属性的存在完全感到困惑。它们是基类属性(TextWriterListener拥有这些属性,并在WriteLine上使用它们)。从类派生的类可以重写方法(XmlWriterTraceListener可以),它可以忽略对TextWriterTraceListener很重要的内容(XmlWriterTraceListener可以忽略这些值)。诊断并不是最好的API,它是在.NET1.0中建立起来的,有很多缺陷(比如提供派生类不使用或不关心的属性的基类),这可以通过反射来控制,虽然不理想,但可行。我个人反编译BCL实现,然后根据自己的喜好定制它们。我喜欢.NET的跟踪功能,但我希望BCL侦听器实现更健壮/可配置。