2009-06-22 7 views
24

try/catch 블록에서 XmlDocument.LoadXml() 같은 것을 사용하지 않고 문자열에 올바른 형식의 XML이 포함되어 있는지 확인할 수있는 방법을 아는 사람이 있습니까? 나는 XML 일 수도 있고 아닐 수도있는 입력을 얻었고, 입력이 try/catch에 의존하지 않고 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가 필요하지 않은 것으로 보입니다. 디버거가 문자열을 확인할 때마다 디버거가 여기에서 깨어지기 때문에 예외가 발생합니다. '성가신 문제로 나를 도와줍니다.

+0

을 던져 도착하는 방법이 있습니다. VS 내에서 바로 가기를 사용하십시오 : Ctrl + Alt + E, System.Xml.XmlException 찾기 및 끄기. – nashwan

답변

21

예외없이 유효성을 검사하는 방법을 알지 못하지만 처리되지 않은 경우 디버거 설정을 으로 만 변경할 수 있습니다. 즉, 코드가 여전히 비 효과적이라 할지라도 즉각적인 문제를 해결할 수 있습니다.

이렇게하려면 디버그/예외/일반 언어 런타임 예외로 이동하여 System.Xml.XmlException을 찾은 다음 "사용자 처리되지 않음"만 선택 표시 (throw되지 않음)해야합니다.

+0

+1이 생명을 살리는 해결책입니다. 실패한 코드를 디버깅해야만 처리 된 예외를 깨는 기능을 사용할 수 있습니다. – OregonGhost

5

IsNullOrEmpty가 중복되는 것을 제외하고는 합리적인 방법입니다 (LoadXml이이를 잘 이해할 수 있음). IsNullOrEmpty를 유지하는 경우 if (! string.IsNullOrEmpty (value))를 수행하십시오.

기본적으로 디버거는 문제가 아니라 코드입니다.

+0

나는 동의하게되었다. 디버거가 예외에서 멈추는 것을 멈추는 디버거 속성 [DebuggerStepThrough]으로 메소드를 마크 업했습니다. –

+0

IsNullOrEmpty는 프로그램에서 많은 일이 발생하는 IsValidXml ("")을 호출 할 때 예외의 오버 헤드를 피하기위한 단순한 최적화입니다. –

3

IsValidXml 메서드에 [System.Diagnostics.DebuggerStepThrough] 특성을 추가하십시오. 이렇게하면 XmlException이 디버거에 의해 포착되는 것을 방지하므로 첫 번째 변경 예외를 catch 할 수 있으며이 특정 메서드는 디버깅되지 않습니다.

1

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

0

나는 문제가 디버거 것을 동의하지 않는다. 일반적으로 예외가 아닌 경우에는 예외를 피해야합니다. 즉, 입력이 올바른 형식의 XML인지 여부에 따라 true/false를 반환하는 IsWellFormed()과 같은 메서드를 찾고있는 경우에는 catch 또는 처리 여부에 관계없이이 구현 내에서 예외가 throw되어서는 안됩니다.

예외는 비싸기 때문에 정상적으로 실행하는 동안 예외가 발생하지 않아야합니다. 예를 들어, 파일의 존재 여부를 확인하고 File.Open을 사용하여 파일이없는 경우 예외를 catch하는 메서드를 작성하는 경우를들 수 있습니다. 이것은 빈약 한 구현 일 것입니다.그 대신에 File.Exists()을 사용해야합니다. (그리고 파일의 존재 여부에 상관없이 예외를 throw하는 try/catch 메서드를 구현하지 않았 으면 좋겠다고 생각합니다.)

+0

이 답변이 도움이 될지 잘 모르겠습니다. 예외를 throw하지 않는 올바른 형식을 확인하는 다른 방법을 제공하지 않았습니다. 그것은 예외를 던지는 방법에 대한 당신의 생각에 대한 진술처럼 보입니다. –

+0

Steve는 try-catch없이이 작업을 수행 할 방법을 명시 적으로 요구하므로 try-catch없이 수행해야한다고 말하면 실제로 풍자에 국한되지 않습니다. –

+0

나는 냉소적 인 시도를하고 있지 않았으며 나는 그 질문에 대답하지 않고 있음을 알고있다. 나는 그것이 명백했다라고 알았다. 나는 다른 의견에 대해 논평했다. 나는 내가 답장하고있는 답장에 답장을 덧붙여 야했다. – nickdu

5

스티브,

우리는 실수로 때로는 XML 대신 JSON 우리를 보낸 제 3 자했다. 이것에 대해 다양한 질문이 주위에있다, 대부분의 사람들은 "쓰레기 - 쓰레기 밖으로"에 동의 -

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)); 
} 
0

그냥 내 2 센트 사실 : 여기 구현하는 것이다. 나는 그와 동의하지 않는다 - 그러나 개인적으로 당신이 쉽게 당신과 쉽게 의사 소통을하지 않는 제 3 자의 xml 데이터를 다루는 경우에 특히, 다음과 같은 빠르고 더러운 솔루션을 발견했다. try/catch -하지만 더 세밀한 입도로 사용하므로 유효하지 않은 xml 문자의 양이 그리 크지 않은 경우에는 도움이됩니다. XmlTextReader 및 해당 메서드 ReadChars()를 각 부모 요소 (명령 중 하나)에 사용했습니다. ReadInner/OuterXml처럼 올바른 형식의 검사를 수행하지 않습니다. Read()와 ReadChars()의 조합은 부모 노드에서 Stubmble 할 때입니다. 물론 XML의 기본 구조는 괜찮다고 가정 할 수 있기 때문에 작동하지만 특정 노드의 내용 (값)은 & ..으로 대체되지 않은 특수 문자를 포함 할 수 있습니다. 이에 상응하는 ... (어딘가에 대한 기사를 찾았지만 현재 소스 링크를 찾을 수 없음)

-1

내 두 센트. 가능 던져지는 예외없이 XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(object)를 사용 <0>some text</0>의 라인을 따라 요소를로드하는이

public bool TryParse(string s, ref XmlDocument result) 
{ 
    try { 
     result = new XmlDocument(); 
     result.LoadXml(s); 
     return true; 
    } catch (XmlException ex) { 
     return false; 
    } 
} 
1

주의 XmlDocument를 사용하여 ... 아주 간단하고 구문 분석에 대해 이후 몇 가지 일반적인 규칙을 따릅니다.

숫자 요소 이름은 유효한 xml이 아니며 제 경우에는 xmlDoc.innerText를 xml의 Sql 서버 데이터 유형에 쓰려고 시도 할 때까지 오류가 발생하지 않았습니다.

지금 검증 및 디버거가 방금 XmlExceptions의 사용자 처리를 전환 할 수 있습니다 문제가있는 경우 예외가
XmlDocument tempDoc = XmlDocument)JsonConvert.DeserializeXmlNode(formData.ToString(), "data"); doc.LoadXml(tempDoc.InnerXml);

+0

좋은 지적 - XML ​​표준은 '후자 뒤에 0 개 이상의 이름 문자 - [4] NameChar :: = Letter | 자릿수 | '.' | '-'| '_'| ':'| CombiningChar | Extender [5] Name :: = (Letter | '_'| ':') (NameChar) * –

관련 문제