簡體   English   中英

創建不帶xmlns名稱空間聲明的XML片段

[英]Create XML fragment without xmlns namespace declaration

我正在嘗試通過代碼創建以下XML:

<log4j:event logger="MyTools" level="WARN" timestamp="763">
  <log4j:message>This is a log message.</log4j:message>
</log4j:event>

但是我無法擺脫添加的xmlns:log4j="http://my-project.org/log4j/" 目前,我正在測試以下代碼(請參見HERE ):

XNamespace ns = "http://my-project.org/log4j/";
var root = new XElement("root", new XAttribute(XNamespace.Xmlns + "log4j", ns));
var eventElement = new XElement(ns + "event");
root.Add(eventElement);

eventElement.SetAttributeValue("logger", "MyTools");
eventElement.SetAttributeValue("level", "WARN");
eventElement.SetAttributeValue("timestamp", DateTime.Now.Millisecond);

eventElement.SetElementValue(ns + "message", "This is a log message.");

當我將eventElement轉換為字符串時,我將名稱空間添加到log4j:event節點中,而將root轉換時,則僅將其添加到根元素中(因為對於有效XML,它應該是IMO),但是如何僅獲取事件節點而不使用僅將名稱空間聲明作為XML片段/節點? 我也嘗試過使用XmlWriter,但結果相同。
我也歡迎其他方式。

目前,我使用String.Replace(" xmlns:log4j=\\"" + ns + "\\"", string.Empty)擺脫它,但這相當慢(使完整方法慢了約50%)由於這種情況可能會以高頻率發生(= logger),因此我想使其盡可能快。
我需要沒有名稱空間聲明的原因是某些日志偵聽器不喜歡該名稱空間,如果該名稱空間存在,則會崩潰(通過UDP將日志發送到日志偵聽器)。

我要改進的是以下NLog渲染器:
https://github.com/NLog/NLog/blob/master/src/NLog/LayoutRenderers/Log4JXmlEventLayoutRenderer.cs
除了緩慢的Replace (請參閱Ln 300)之外,我還替換了callsite / UserStackFrame以使用[CallerMemberName]參數,此類參數由我自己的日志包裝器實現。 當僅將名稱空間留在其中時,我可以將測試系統上的日志生成時間從> 100ms / 1k加快到〜35ms / 1k(因為對於有效的XML應該如此),但是正如某些日志偵聽器(即Sentinel)所說的那樣當它在那里時崩潰...

您顯示的代碼段在沒有名稱空間的XML領域中格式良好,如果您確實需要使用.NET創建這樣的代碼段,則舊版XmlTextWriter允許如下:

        using (StringWriter sw = new StringWriter())
        {

            using (XmlTextWriter xtw = new XmlTextWriter(sw))
            {
                xtw.Namespaces = false;
                xtw.Formatting = Formatting.Indented;
                xtw.WriteStartElement("log4j:event");
                xtw.WriteAttributeString("logger", "MyTools");
                xtw.WriteAttributeString("level", "WARN");
                xtw.WriteAttributeString("timestamp", "763");
                xtw.WriteElementString("log4j:message", "This is a log message.");
                xtw.WriteEndElement();
            }
            string result = sw.ToString();
            Console.WriteLine(result);
        }

結果:

<log4j:event logger="MyTools" level="WARN" timestamp="763">
  <log4j:message>This is a log message.</log4j:message>
</log4j:event>

但是請注意,當今大多數XML解析器和API都希望使用命名空間格式良好的XML(僅當冒號之前的前綴綁定到命名空間時才允許使用帶有冒號的名稱),因此無法使用LINQ to XML處理創建的代碼段。例如,或使用XmlReader.Create創建的默認XmlReader。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM