Windows Phone 72011.11.08 11:46

이번에 코레일 프로젝트를 맞게 되었다.

하지만 코레일은 EUC-KR로 된 XML이였고 윈폰과 실버라이트는 지원하지 않았다.

하지만 어떤 고마우신분이 라이브러리를 제공해 주셧다 프로젝트 시작하기 3일전에… 타이밍!!!

일단 외부에서 EUC-KR로 된 xml파일을 윈폰에서 사용하는 방법

 

public void GetXmlData(Action<Dictionary<string, string>, Exception> callback, string url)
{
    WebClient webClient = new WebClient();
    webClient.OpenReadAsync(new Uri(url));
    webClient.OpenReadCompleted += (s, e) =>
        {
            Stream readStream = e.Result;
            Byte[] euckrXML = new Byte[readStream.Length];

            readStream.Read(euckrXML, 0, euckrXML.Length);
            readStream.Close();

            var temp = EUCKR_Unicode_Converter.GetUnicodeString(euckrXML);
            XmlReader reader = XmlReader.Create(new StringReader(temp));
            XElement xe = XElement.Load(reader);

            //상위 element data
            Dictionary<string, string> dict = new Dictionary<string, string>();
            foreach (var item in xe.Elements())
            {
                dict.Add(item.Name.LocalName, item.Value);
            }

            //다수의 하위 elements data
            var query = from item in xe.Descendants("trn_infos").Descendants("trn_info")
                        select item;

            List<Dictionary<string, string>> trnsInfos = new List<Dictionary<string, string>>();
            foreach (XElement item in query)
            {
                Dictionary<string, string> trnInfo = new Dictionary<string, string>();
                foreach (XElement subItem in item.Elements())
                {
                    trnInfo.Add(subItem.Name.LocalName, subItem.Value);
                }
                trnsInfos.Add(trnInfo);
            }

            //출력
            foreach (var item in trnsInfos)
            {
                foreach (var subItem in item)
                {
                    Debug.WriteLine("{0}:{1}", subItem.Key, subItem.Value);
                }
            }

            callback(dict, null);
        };
}

 

위의 XElement 까지만 참고하면 될꺼 같다.

나머지 소스는 그냥 xml을 dictionary로 바꾸기 위한 소스코드이다.

자 이제 euc-kr은 문제 없이 웹으로 부터 받아서 파싱 가능한 상태이다.

그렇다면 보낼때는 어떻게 해야할까?

내가 원하는 결과 값 : 서울 -> "%BC%AD%BF%EF"

이다. 원래 같았으면

string encodingResult = HttpUtility.UrlEncode(url);

이런식으로 urlencode를 이용하겠지만  이렇게

해서 해결하였다.

Byte[] temp = EUCKR_Unicode_Converter.GetEucKRString("서울");
StringBuilder sb = new StringBuilder();
foreach (byte b in temp)
{
    sb.AppendFormat("%{0:x}", b);
}

sb.tostring();

카일로님이 만드신 소스 정말 유용한거 같다.^^

원본 소스다.

Posted by 동동(이재동)

댓글을 달아 주세요

  1. 카일로

    잘쓰셨다니 다행이네요.

    오히려 저는 보낼때 어떻게 하면 될까 해서.. 직접 짤까.. 하고나서 짠담에..

    혹시 누군가가 짜놓지는 않았을가.. 검색해보니

    이미 해놓으셨었군요. 검색 미리해볼껄 ^^

    유일하게 다른점은 전 appendformat을 안쓰고

    stringBuilder.Append("%");
    stringBuilder.Append(b.ToString("X2")); // in HexaDecimal

    요렇게 했네요 ^^

    2011.11.20 01:11 [ ADDR : EDIT/ DEL : REPLY ]
  2. 카일로

    아 맞다. 참고로 코레일 api는 제가 써본적은 없으나

    우체국의 경우 euc-kr로 url을 보내더라도 아마 안나올텐데

    webClient.Headers["accept-language"] = "ko"

    이 줄 추가해주면 잘~~ 작동할겁니다.



    맞다 그리고 한가지 살~짝 님 코드 디버깅 하자면

    sb.AppendFormat("%{0:x}", b);

    여기서 에러가 생길 가능성이 있는데요

    http://www.w3.org/Addressing/URL/url-spec.txt

    w3협회에 따르면 %뒤에 바이트는 반드시 두글짜로 하라고 되어 있습니다. 따라서 15 이하의 숫자는 %03 대신 %3 이런식으로 나올텐데, 따라서 포맷팅에서 반드시 두글짜 출력하도록 고쳐야 하겠네요

    x2 라고 하면 될겁니다 아마 (제가 그렇게 했으니;;)

    2011.11.20 01:14 [ ADDR : EDIT/ DEL : REPLY ]
  3. 카일로

    url을 집어 넣으면 euc-kr기반 url로 바꿔주는 메서드 추가해서 라이브러리 만들어 봤습니다.


    윈모데브에 업댓했고요 ^^

    2011.11.20 02:38 [ ADDR : EDIT/ DEL : REPLY ]
  4. 앗 안녕하세요^^

    좋은 가르침 감사합니다~

    라이브러리 아주 잘쓰고 있습니다 ㅎㅎ

    앞으로도 많은 가르침 부탁 드려요~^^

    2011.11.21 11:11 신고 [ ADDR : EDIT/ DEL : REPLY ]
  5. 이봉호

    감사합니다. 소스 잘 받았습니다. 저는 Silverlight에서 사용중인데 잘 돌아가네요^^

    2014.02.28 17:17 [ ADDR : EDIT/ DEL : REPLY ]

iPhone App2011.09.08 11:20

로그인 작업을 할때 특수문자나 한글이 들어갔을때 에러가 나지 않게 하기 위해서는 URL을 인코딩해야 한다.   

NSString *urlString =[NSString stringWithFormat:@"http://주소/Member/MemberSelect?id=%@&pw=%@",_userID.text,_userPW.text];

  

NSString *escapedUrl = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

  

NSURL *XMLURL =[NSURL URLWithString:escapedUrl];


참조 : http://www.digipine.com/programming/6119

Posted by 동동(이재동)

댓글을 달아 주세요

  1. 주용준

    고맙습니다. 퍼가용~

    2016.01.02 18:04 [ ADDR : EDIT/ DEL : REPLY ]

iPhone App2011.07.22 18:51

일단 내가 하고 싶었던것은 GET방식의 URL을 HttpRequest 를 해서 WCF에 전송하게 한뒤 글을 쓰게 만드는것이 목표였다.

일단 헤더에 NSMutableData를 만들고

-(void) save{

responseData = [NSMutableData new];

NSString *serviceURL = [NSString stringWithFormat:@"http://192.168.10.3:9090/hugeboardservice/write?name=%@&title=%@&description=%@",

[self encodeString:nameTextField.text],

[self encodeString:titleTextField.text],

[self encodeString:descriptionTextView.text]];


NSURL *url = [NSURL URLWithString:serviceURL];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];

  

[request setHTTPMethod:@"GET"];

  

[[NSURLConnection alloc] initWithRequest:request delegate:self];

[self.navigationController popViewControllerAnimated:YES];

}


이렇게 했다 저기 위에 보면 NSURLConnectino을 delegate 받았다.


그래서 추가적으로 4개의 델리게이트 메소드를 만들었다.


- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

[responseData setLength:0];

}


- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

[responseData appendData:data];

}


- (void) connectionDidFinishLoading:(NSURLConnection *)connection {

[connection release];

  

NSString* responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

NSLog(@"the html from google was %@", responseString);

  

[responseString release];

}


-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {

NSLog(@"something very bad happened here");

}


참고한곳은 http://toranbillups.com/blog/archive/2011/04/10/Writing-your-first-http-request-in-objective-c


여기이다.

하지만 이렇게 하다보니 문제가 생겼다 한글을 파라미터로 하면 오류가 났던것이다. 아마 인코딩을 안해서 그렇다고 생각해서


//한글떄문에 엔코딩하기 위해서 만든 메소드

-(NSString *)encodeString: (NSString*) unencodedString{

NSString *temp = (NSString *)CFURLCreateStringByAddingPercentEscapes(

NULL,

(CFStringRef)unencodedString,

NULL,

(CFStringRef)@"!*'();:@&=+$,/?%#[]",

kCFStringEncodingUTF8 );

  

return temp;

}


이런 메소드를 추가로 만들었다
만드는데 참고한 사이트는
http://simonwoodside.com/weblog/2009/4/22/how_to_really_url_encode/


***추가***

save를 하고 뒤로 가기 위해서 save메소드에 

[self.navigationController popViewControllerAnimated:YES];

이걸 넣었는데

여기에 넣는게 아니라 

- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { [responseData setLength:0]; [self.navigationController popViewControllerAnimated:YES]; }

이쪽에 넣는것이 맞다. 한마디로 작업이 완료가 되면 뒤로 넘어가야지 바로 넘어가면 안되는것이다.

참고 : http://www.pcraft.kr/101


Posted by 동동(이재동)

댓글을 달아 주세요