2011-01-24 2 views
7

웹 서비스에서 가져온 XML 데이터가있는 문자열이 있습니다. 데이터가 추악하고 xml의 이름 태그에 잘못된 문자가 있습니다. 예를 들어 다음과 같이 표시 될 수 있습니다.XML 이름 태그에서 잘못된 문자 제거 - RegEx C#

<Author>Scott the Coder</Author><Address#>My address</Address#> 

[주소 이름] 필드의 #가 잘못되었습니다. 이름 태그에서 모든 잘못된 문자를 제거하지만 XML의 Value 섹션에 모든 문자를 남기는 정규식을 찾고 있습니다. 즉, RegEx를 사용하여 시작 이름 태그와 종료 이름 태그에서만 문자를 remvove 싶습니다. 다른 모든 것은 똑같은 것을 다시 말해야합니다.

는 아직 모든 잘못된 문자를 가지고 있지 않지만,이 날이 시작됩니다 : # {} &()

은 내가 할 노력하고 무엇을 할 수 있습니까?

+2

"XML 데이터"와 같은 것을 언급하지 않는 것이 좋습니다. 그것은 XML이 아닙니다. 그래서 당신이 그 문제에 곤란을 겪고있는 것입니다. 데이터 공급 업체가 그들의 출력물이 쓰레기라는 사실을 알고 있어야합니다. –

+1

예, 그게 내가해야 할 일입니다. 이 메시지 게시판에서 문제를 해결하는 동안 일을 시도하고 단순화 할 이유가 없습니다. 나는 그 사람을 사냥해서 나쁜 소년이라고 말해야 해. 그건 내 문제를 해결할거야 .... 어, 잠깐, 아니 .. 나는 여전히 같은 문제가있다 ... 다음! – Scott

+0

허용되지 않는 문자에'$'를 추가 할 수 있습니다. – TinyTimZamboni

답변

1

두 개의 텍스트 영역과 하나의 버튼이있는 간단한 양식을 사용했습니다. 이것은 트릭을 할 것으로 보인다.

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Text.RegularExpressions; 

namespace WindowsFormsApplication3 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      Regex r = new Regex(@"(?<=\<\w+)[#\{\}\(\)\&](?=\>)|(?<=\</\w+)[#\{\}\(\)\&](?=\>)"); 
      textBox2.Text = r.Replace(textBox1.Text, new MatchEvaluator(deleteMatch)); 
     } 

     string deleteMatch(Match m) { return ""; } 
    } 
} 
+0

문자열이 거대 할 수 있으므로 문자열을 두 번 이상 검색하지 않도록 노력하고 있습니다. 그러나 깨끗한 RegEx 방법을 찾지 못한다면, 그냥 그 일을하는 파서를 작성해야 할 것입니다. – Scott

+0

이제는 더 잘 이해합니다. 이것은 도움이 될만한 것 같습니다 : http://www.perlmonks.org/?node_id=518444 (나는 펄서 파트가 아니라 앞을 내다 본다.) 좋아, C# regexp에 대해 찾았습니다. (? = ...) \t 긍정적 인 미리보기 (?! ...) \t 부정적인 표제 (? <= ...) \t 긍정적 인 look-behind입니다. (? Marco

1

RegEx는 처리 할 파일이 하나만있는 경우가 아니라면 문제가되는 방법입니다. 고통, 좌절, 버그가 당신의 미래 ...

입니다 내가 당신 정말는 정규식을 사용하려면, 내가 Perl로 사용하고 유용한 것들 HERE있다.

대신 파서를 사용 해본 적이 있습니까?

고려해야 할 :

XmlDocument

LINQ for XML 일단 구문 분석, 당신은 귀찮은 부분을 다시 저장하거나 당신의 프로그램에 길을 갈 수 있습니다.

+0

이러한 문자가 태그 이름에 유효한지 여부는 확실하지 않지만, 그렇지 않은 경우 xml을 구문 분석하지 못할 수도 있습니다 (실제로이 질문에 이르게 할 수 있습니다). 당신이 그것을 분석 할 수 있다면, 당신은 그것을 고칠 필요가 없습니다. 서로 다른 파서를 생각해 볼 가치가 있습니다. – Kobi

+0

실제로 XMLDocument는 내 문제입니다. XMLDocument는 xmlDoc.LoadXml (xmlString)을 throw합니다. 파서를 통해 실행하기 전에 수정해야합니다. 내가 이해하지 못하는 XMLDocument에 관한 것이 없다면, 나는이 방법으로 사용하지 않을 것이다 ?? – Scott

+0

@Kobi이 모든 문자는 요소 이름에 유효하지 않습니다. 이 XML 파서는이 입력을 받아들이지 않습니다. –

5

Xml 노드의 이름의 유효성 만 검사하려는 경우 XmlConvert 클래스를 살펴 보시기 바랍니다. 특히 VerifyNameVerifyNCName 방법.

또한이 클래스를 사용하면 EncodeNameEncodeLocalName 방법을 사용하여 텍스트를 노드 이름으로 사용할 수 있습니다.

이러한 방법을 사용하면 정규식을 수행하는 것보다 훨씬 쉽고 안전하며 빠릅니다.

+1

Verify * Name 메서드는 성능이 좋지 않은 예외를 throw합니다. – hcoverlambda

1

이를 시도해보십시오 내다 성공

s = Regex.Replace(s, @"[#{}&()]+(?=[^<>]*>)", ""); 

경우, 경기 후 다음 꺾쇠 괄호가있는 오른쪽을 가리키는 하나 (>을), 경기가 태그 내부에 발생했음을 나타냅니다.

물론 이것은 텍스트가 합리적으로 잘 형성되어 있고 태그에있는 태그와 별도로 꺾쇠 괄호가 없다고 가정합니다.

1

문자열 교체를 사용하여 잘못된 모든 잘못된 문자를 대체 할 수 있습니다. 일반적으로 ASCII 제어 문자는 XML 읽기에 문제를 만듭니다.

사용이 기능

 public static string CleanInvalidXmlChars(this string text) 
    { 
     // From xml spec valid chars: 
     // #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]  
     // any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. 
     string re = @"[^\x09\x0A\x0D\x20-\xD7FF\xE000-\xFFFD\x10000-x10FFFF]"; 
     return Regex.Replace(text, re, ""); 
    } 


    xmlcontent = xmlcontent.CleanInvalidXmlChars(); 

이 정규 표현식에 지정된 chracters을 정리합니다를 방지 할 수 있습니다. i get this from this site

+0

이 정규식은 "x10FFFF"앞에 "\"가 없다고 생각합니다. 예를 들어 \ x10을 제거하지 않습니다. –