web-dev-qa-db-ja.com

try / catchなしで整形式のXMLをチェックしますか?

誰かが、try/catchブロックでXmlDocument.LoadXml()のようなものを使用せずに、文字列が整形式のXMLを含むかどうかを確認する方法を知っていますか? XMLである場合とそうでない場合がある入力があります。速度と例外ではない状況では発生しない一般的な原則の両方のために、try/catchに依存しない限り、その入力がXMLではない可能性があることを認識するコードが必要です。例外。現在、これを行うコードがあります。

private bool IsValidXML(string value)
    {
        try
        {
            // Check we actually have a value
            if (string.IsNullOrEmpty(value) == false)
            {
                // Try to load the value into a document
                XmlDocument xmlDoc = new XmlDocument();

                xmlDoc.LoadXml(value);

                // If we managed with no exception then this is valid XML!
                return true;
            }
            else
            {
                // A blank value is not valid xml
                return false;
            }
        }
        catch (System.Xml.XmlException)
        {
            return false;
        }
    }

しかし、try/catchを必要としないもののようです。例外はデバッグ中に陽気な地獄を引き起こしています。これは、文字列をチェックするたびにデバッガがここで壊れ、厄介な問題を解決するためです。

25
Steve Cooper

例外なく検証する方法はわかりませんが、デバッガーの設定を変更して、XmlExceptionが処理されない場合にのみブレークするように変更できます。これにより、コードが依然として洗練されていない場合でも、差し迫った問題を解決できます。

これを行うには、Debug/Exceptions .../Common Language Runtime Exceptionsに移動し、System.Xml.XmlExceptionを見つけて、「User-unhandled」だけがチェックされている(スローされていない)ことを確認します。

23
Jon Skeet

スティーブ、

XMLの代わりにJSONを誤って送信してしまうサードパーティがありました。これが私が実装したものです:

public static bool IsValidXml(string xmlString)
{
    Regex tagsWithData = new Regex("<\\w+>[^<]+</\\w+>");

    //Light checking
    if (string.IsNullOrEmpty(xmlString) || tagsWithData.IsMatch(xmlString) == false)
    {
        return false;
    }

    try
    {
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.LoadXml(xmlString);
        return true;
    }
    catch (Exception e1)
    {
        return false;
    }
}

[TestMethod()]
public void TestValidXml()
{
    string xml = "<result>true</result>";
    Assert.IsTrue(Utility.IsValidXml(xml));
}

[TestMethod()]
public void TestIsNotValidXml()
{
    string json = "{ \"result\": \"true\" }";
    Assert.IsFalse(Utility.IsValidXml(json));
}
8
Greg Finzer

これは、IsNullOrEmptyが冗長であることを除いて、適切な方法です(LoadXmlはそれをうまく理解できます)。 IsNullOrEmptyを維持する場合は、if(!string.IsNullOrEmpty(value))を実行します。

基本的には、デバッガーが問題であり、コードではありません。

5

[System.Diagnostics.DebuggerStepThrough]属性をIsValidXmlメソッドに追加します。これにより、XmlExceptionがデバッガーにキャッチされないようにします。つまり、最初の変更の例外のキャッチをオンにでき、この特定のメソッドはデバッグされません。

4
Steve Cooper

XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(object)withoutを使用して_<0>some text</0>_の行に沿って要素をロードできるようにするため、XmlDocumentを使用する場合の注意:例外がスローされます。

数値要素名は有効なxmlではありません。私の場合、xmlDoc.innerTextをxmlのSQLサーバーデータ型に書き込もうとするまでエラーは発生しませんでした。

これが私が今検証する方法であり、例外がスローされます
XmlDocument tempDoc = XmlDocument)JsonConvert.DeserializeXmlNode(formData.ToString(), "data"); doc.LoadXml(tempDoc.InnerXml);

2
TimDude

XmlTextReaderクラスはXmlReaderの実装であり、高速でパフォーマンスの高いパーサーを提供します。 XMLは整形式でなければならないという規則を適用します。 DTDやスキーマ情報がないため、検証パーサーでも検証パーサーでもありません。ブロック単位でテキストを読み取るか、ストリームから文字を読み取ることができます。

XMLストリームのコンテンツ全体を読み取るコードを追加した別のMSDN記事の例。

string str = "<ROOT>AQID</ROOT>";
XmlTextReader r = new XmlTextReader(new StringReader(str));
try
{
  while (r.Read())
  {
  }
}
finally
{
  r.Close();
}

ソース: http://bytes.com/topic/c-sharp/answers/261090-check-wellformedness-xml

1
Shivanath D

問題はデバッガーであることに同意しません。一般に、例外的でない場合は、例外を回避する必要があります。これは、入力が整形式のXMLかどうかに基づいてtrue/falseを返すIsWellFormed()のようなメソッドを誰かが探している場合、キャッチされているかどうかに関係なく、この実装内で例外がスローされないことを意味しますそして扱われるかどうか。

例外は高価であり、正常な実行が正常に行われている間は発生しません。たとえば、ファイルの存在を確認するメソッドを記述し、File.Openを使用して、ファイルが存在しない場合に例外をキャッチします。これは貧弱な実装になります。代わりにFile.Exists()を使用する必要があります(その実装では、ファイルが存在しない場合に例外をスローするメソッドを単にtry/catchで囲むのではなく、存在しないと確信しています)。 。

0
nickdu

ちょうど私の2セント-これについてはさまざまな質問があり、ほとんどの人が「ガベージイン-ガベージアウト」という事実に同意しています。私はそれに同意しません-しかし、個人的には、簡単に通信できないサードパーティからのxmlデータを扱う場合に特に、次の迅速で汚い解決策を見つけました。try/の使用を避けませんキャッチ-しかし、より細かい粒度で使用するため、無効なxml文字の量がそれほど大きくない場合に役立ちます。コマンドの1つである各親要素に対してXmlTextReaderとそのメソッドReadChars()を使用しましたこれは、ReadInner/OuterXmlのように整形式のチェックを行いません。つまり、Read()が親ノードにスタブリングする場合、Read()とReadChars()の組み合わせになります。もちろん、これは機能します。XMLの基本構造は問題ないと想定できるからです。ただし、特定のノードのコンテンツ(値)には、&..で置き換えられていない特殊文字を含めることができます。同等...(これについての記事をどこかで見つけましたが、現時点ではソースリンクが見つかりません)

0
hello_earth