2011-07-07 21 views
6

サードパーティのプロバイダからXMLファイルを解析していますが、一部の要素に重複した属性が含まれているため、C#でXMLから重複する属性を削除する方法

私はソースを管理する権限がありません。どの要素に重複する属性があるのか​​わかりませんし、あらかじめ重複する属性名を知っているわけでもありません。

もちろん、XMLDocumentオブジェクトにコンテンツをロードすると、重複した上なXmlExceptionはので、私はしかし、私は要素によってXML要素もののステップと、私は問題のある要素を取得するとき、重複属性に対処するXmlReaderを使用することができます属性を提起します。

ただし、reader.Read()XmlExceptionが発生してから、要素の属性を調べる機会があります。

public static void ParseTest() 
{ 
    const string xmlString = 
     @"<?xml version='1.0'?> 
     <!-- This is a sample XML document --> 
     <Items dupattr=""10"" id=""20"" dupattr=""33""> 
      <Item>test with a child element <more/> stuff</Item> 
     </Items>"; 

    var output = new StringBuilder(); 
    using (XmlReader reader = XmlReader.Create(new StringReader(xmlString))) 
    { 
     XmlWriterSettings ws = new XmlWriterSettings(); 
     ws.Indent = true; 
     using (XmlWriter writer = XmlWriter.Create(output, ws)) 
     { 
      while (reader.Read()) /* Exception throw here when Items element encountered */ 
      { 
       switch (reader.NodeType) 
       { 
        case XmlNodeType.Element: 
         writer.WriteStartElement(reader.Name); 
         if (reader.HasAttributes){ /* CopyNonDuplicateAttributes(); */} 
         break; 
        case XmlNodeType.Text: 
         writer.WriteString(reader.Value); 
         break; 
        case XmlNodeType.XmlDeclaration: 
        case XmlNodeType.ProcessingInstruction: 
         writer.WriteProcessingInstruction(reader.Name, reader.Value); 
         break; 
        case XmlNodeType.Comment: 
         writer.WriteComment(reader.Value); 
         break; 
        case XmlNodeType.EndElement: 
         writer.WriteFullEndElement(); 
         break; 
       } 
      } 

     } 
    } 
    string str = output.ToString(); 
} 

入力を解析し、正規表現と文字列操作を使用せずに重複して属性を削除する別の方法があります:

ここで問題を実証するサンプル方法がありますか?

+0

XMLプロセッサAPIプロバイダが処理に接続してエラー状態を処理できるようにするフックだけが可能です。 – Ankur

+0

興味深い問題ですが、解決策を楽しみにしています! –

+2

あなたの入力はXMLではないので、XMLを使ってこの問題を解決する方法はありません。あなたは入力を制御できないと言っていますが、ベンダがXMLを送信していないことを上司に少なくとも認識させることはできますか? _vendor_がこれを知っていることを少なくとも確認できますか?このデータを送信するのに十分な愚かな組織は、それがXMLではないことに気づかないほど愚かかもしれません。 –

答えて

3

XMLをHTMLドキュメントと考えて解決策を見つけました。その後、オープンソースのHtml Agility Packライブラリを使用して、有効なXMLを取得できました。

まず、xmlをHTMLヘッダーで保存してください。
だから、このようなHTMLの宣言でXML宣言
<?xml version="1.0" encoding="utf-8" ?>
を置き換える:
内容がファイルに保存されたら !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

、この方法は有効なXMLドキュメントが返されます。

// Requires reference to HtmlAgilityPack 
public XmlDocument LoadHtmlAsXml(string url) 
{ 
    var web = new HtmlWeb(); 

    var m = new MemoryStream(); 
    var xtw = new XmlTextWriter(m, null); 

    // Load the content into the writer 
    web.LoadHtmlAsXml(url, xtw); 

    // Rewind the memory stream 
    m.Position = 0; 

    // Create, fill, and return the xml document 
    XmlDocument xmlDoc = new XmlDocument(); 
    xmlDoc.LoadXml((new StreamReader(m)).ReadToEnd()); 
    return xmlDoc; 
} 

重複した属性ノードが自動的に以前のものを上書きし、後に属性値をを除去しました。

0

OK]をクリックしてエラーをキャッチする必要があると思う:

その後、あなたは次の方法を使用することができるはずです。次のプロパティを取得するために

reader.MoveToFirstAttribute(); 

reader.MoveToNextAttribute() 

を:

reader.Value 
reader.Name 

これにより、すべての属性値を取得できます。

+0

エラーを捕捉して現在のノードの属性を処理することができます(つまり重複しないコピー)が、 'reader.Read()'がfalseを返すので、文書の残りの部分を処理し続けるので、要素は処理されなくなります。 – Catch22

+0

#Catch22、うん、コードを再開しようとしている間、私はそれを見つけました。私はあなたの周りに道を見つけることを望んだ。ここをクリックしてください:http://bytes.com/topic/c-sharp/answers/827965-how-handle-xml-parsing-exceptionそれはXMLReaderが理由でエラーに耐えられないように見えます。これは通常は良いニュースですが、あなたのケースでは、私の提案された解決策はおそらく動作しません。ごめんなさい – openshac

関連する問題