2016-08-22 4 views
0

せずにXMLフラグメントを作成します。私はコードを経由して、次のXMLを作成しようとしていますのxmlns名前空間宣言

<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/"を取り除くために管理していないが追加されました。 (として私は文字列にeventElementを変換すると

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."); 

を私は名前空間がlog4j:eventノードに追加し、rootを変換するときに、それが唯一のルート要素に追加され得る:現時点では、私は、次のコードをテストしてい(HEREを参照してください)有効なXMLの場合はIMOである必要があります)、イベントノードをXMLフラグメント/ノードのみの名前空間宣言なしで取得する方法はありますか? 私はXmlWriterを使ってみましたが、同じ結果がありました。
私は他のaproachesにもオープンしています。

現時点では私はString.Replace(" xmlns:log4j=\"" + ns + "\"", string.Empty)を使用していますが、それはむしろ遅いです(完全な方法を〜50%遅くします)。これは高頻度(=ロガー)で発生する可能性があるためできるだけ早く
名前空間宣言なしで必要とするのは、一部のログリスナーが名前空間を気に入らずクラッシュしている場合です(ログはUDP経由でログリスナーに送信されます)。私が改善しようとしています何

は、次のNLogレンダラです:
https://github.com/NLog/NLog/blob/master/src/NLog/LayoutRenderers/Log4JXmlEventLayoutRenderer.cs
別に遅いReplaceから(LN 300を参照してください)私も自分自身のログによって実装[CallerMemberName]パラメータと、そのようなを使用するために呼び出し場所/ UserStackFrameを置き換えますラッパー。有効なXMLのために名前空間を残すだけで、テストシステムの> 100ms/1kログから〜35ms/1kまでのログ生成をスピードアップすることができましたが、既にいくつかのログリスナー(Sentinel)あなたがそこにいるときにクラッシュします...

+1

あなたが得ようとしているのは 'notXml'です。 XMLで動作するツールでは、それ以外のものを生成することは期待できません。正しく構成されたXMLを正しく扱うことができないツールがある場合は、それらを修正することを検討する必要があります。名前空間接頭辞、*は単独で意味を持ちません。名前空間接頭辞が名前空間宣言に関連付けられている場合にのみ、正しいセマンティクスを取得します。 –

+0

@Damien_The_Unbeliever:私はそれが有効ではないXMLを「単独で」知っています。そのため、私はそれを「XML断片」と呼んでいます。事実、私はXML構造やそれを聞くのに使われたツールを変更することはできません。両方が手に入らず、できるだけ早く一緒に作業するよう努力しています。 – ChrFin

+0

あなたはかっこを間違った場所。 Elementの代わりにAttributeに 'ns'を追加しています:new XElement( "root"、新しいXAttribute(XNamespace)。Xmlns + "log4j")、ns); – jdweng

答えて

1

あなたが示したスニペットは、ネームスペースのない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 XML、またはXmlReader.Createで作成されたデフォルトのXmlReader。

+0

おかげさまで、これは私が必要としていたものでした。他の2つのアプローチ(今は〜30ms/1kログ)よりもわずかに高速です。 – ChrFin

関連する問題