1 Results for '정규표현식'

  1. 2007.06.04 [Silverlight] QuickStarts, HTML DOM의 사용
Silverlight 1.1 바로 시작하기

HTML DOM의 사용
준비 사항
Silverlight 개발의 기초에서 개발에 필요한 도구와 기술에 대해 설명하고 있습니다.
이벤트 핸들링에서 개체의 이벤트를 처리하는 방법에 대해 설명하고 있습니다.

HTML DOM(Document Object Model)과 JavaScript에 대한 사전 지식이 필요합니다. http://www.cadvance.org/ 에 HTML부터 XML까지 아주 잘 정리되어 있으니 참고하시기 바랍니다.

예제 중간에 정규표현식이 사용되며 여기에 대한 자세한 설명은 http://msdn2.microsoft.com/ko-kr/library/hs600312(VS.80).aspx 을 참고하십시오.

이 글에서 사용된 예제는 http://gongdo.oranc.co.kr/Silverlight/Samples/HtmlDom/TestPage.html 에서 미리 테스트해볼 수 있습니다.

HTML DOM 참조

호스트 HTML의 DOM에 접근하는 방법
Silverlight는 System.Windows.Browser 네임스페이스를 통해 호스트 HTML의 DOM에 접근하고 핸들링 할 수 있는 클래스들을 제공합니다.


매니지드 코드에서 HTML DOM에 접근하는 방법을 알아보기 전에 사용자와 상호작용이 가능한 간단한 HTML 페이지를 만들어 보겠습니다. 또한 이 예제는 Silverlight내의 매니지드 코드로 HTML DOM에 접근하는 방법을 보여주기 위한 것이므로 XAML 디자인도 간소화 하였습니다.

Howto:5-1 사용자와 상호작용하는 HTML 페이지 샘플 및 XAML 페이지 디자인
1. HtmlDom이라는 이름으로 새 Silverlight 프로젝트를 생성합니다.

2. TestPage.html의 BODY태그 안에 다음 DIV 코드 블럭을 추가합니다.
HTML
<div id="userInteraction">
    <p style="font-size:20px; font-weight:bold;">매니지드 코드에서 HTML DOM 접근 예제</p>
    <span style="font-size:14px">1. HTML DOM의 이벤트 핸들링</span><br />
    예제 1) e-mail 유효성 검사 :
    <input type="text" id="email" size="50px" /><input type="button" id="emailSubmit" value="체크" /><br />
    <span style="margin-left:50px">검사 결과 : </span>
    <input type="text" id="emailValidationResult" size="70" /><br /><br />

    <span style="font-size:14px">2. 호스트 HTML 페이지의 속성 얻기</span><br />
    예제 2) 페이지 속성 정보 : 
    <input type="button" id="propertiesSubmit" value="속성 가져오기" /><br />
    <textarea id="properties" cols="70" rows="7"></textarea><br /><br />

    <span style="font-size:14px">3. HTML DOM의 메소드 호출</span><br />
    예제 3) URL 유효성 검사 및 이동 : 
    <input type="text" id="url" size="30" /><input type="button" id="urlSubmit" value="체크 & 이동" /><br /><br />
</div>

예제는 1. 간단한 이메일 유효성 검사, 2. HTML 페이지의 속성 얻기, 3. HTML DOM의 메소드 호출하는 방법 입니다.

3. Page.xaml의 루트 엘리먼트인 Canvas를 300 x 50 픽셀로 설정하고 TextBlock 하나를 선언합니다. 다른 HTML 엘리먼트와 구분하기 위해 배경 색상을 따로 설정하였습니다.
XAML
<Canvas x:Name="parentCanvas"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Loaded="Page_Loaded"
    x:Class="HtmlDom.Page;assembly=ClientBin/HtmlDom.dll"
    Width="300" Height="50" Background="#FFFF9966">
    <TextBlock Text="Access HTML DOM from managed code." />
</Canvas>

4. TestPage.html.js에서 호스팅할 Silverlight 컨트롤의 크기도 300 x 50으로 설정합니다.
Script
//...전략...
    properties: {
        width: "300",
        height: "50",
//...후략...

매니지드 코드에서 HTML DOM에 접근하기 위해서 다음과 같은 코드를 사용합니다.

C#
using System.Windows.Browser;
HtmlDocument document = HtmlPage.Document;

앞서 얘기했듯이 System.Windows.Browser 네임스페이스는 자신을 호스팅하는 HTML 페이지에 접근하기 위한 다양한 클래스와 메소드를 제공합니다. 호스트 HTML 페이지는 HtmlPage 클래스로 캡슐화되고 HtmlDocument 클래스는 HTML DOM 그 자체를 캡슐화 하며 HtmlPage의 Document 프로퍼티를 통해 호스트 HTML의 HTML DOM에 대한 참조를 얻을 수 있습니다.

HTML DOM 엘리먼트의 이벤트 핸들링
HtmlPage.Document 프로퍼트를 통해 얻은 HTML DOM에 대한 참조를 사용하여 HTML DOM 엘리먼트에 대한 이벤트 핸들러를 매니지드 코드로 작성한 함수로 지정할 수 있습니다. 여기에서는 앞에서 작성한 HTML 페이지의 1번 예제를 처리하는 방법을 제시합니다.
Howto:5-2 HTML DOM 엘리먼트의 이벤트 핸들링
1. Page.xaml.cs에 HTML 페이지 정보 처리와 정규 표현식 처리를 위한 네임스페이스를 추가하고 HTML DOM에 대한 참조를 클래스의 지역 변수에 저장합니다.
C#
// 다음 네임스페이스를 추가
using
System.Windows.Browser;

using System.Text.RegularExpressions;

// 프로젝트의 네임스페이스 선언은 생략
public partial class Page : Canvas
{
    HtmlDocument _document; // HTML DOM 참조
    public void Page_Loaded(object o, EventArgs e)
    {
        // Required to initialize variables
        InitializeComponent();
        _document = HtmlPage.Document;
    }
}

2. 예제 1의 버튼 클릭 이벤트를 받아서 처리할 이벤트 핸들러를 선언합니다. 내부 코드는 아래에서 추가하도록 하고 여기에서는 단지 이름만을 선언해 놓습니다.
C#
private void OnEmailClicked(object sender, HtmlEventArgs e)
{
}

3. 클래스의 생성자에 HTML DOM 참조로부터 실제로 이벤트를 부여할 엘리먼트의 참조를 얻고 이벤트 핸들러를 지정하는 코드를 추가합니다. 과정 2에서 미리 이벤트 핸들러를 선언했기 때문에 코드 입력 과정에서 인텔리센스의 도움을 받을 수 있습니다.
C#
// 예제1의 버튼 ID를 통해 이벤트 핸들러 지정
HtmlElement btnEmail = _document.GetElementByID("emailSubmit");
btnEmail.AttachEvent("onclick", new EventHandler<HtmlEventArgs>(this.OnEmailClicked));

4. 이제 실제 작동할 이벤트 핸들러 코드를 작성합니다.
C#
private void OnEmailClicked(object sender, HtmlEventArgs e)
{
    // 엘리먼트의 참조 얻기

    HtmlElement txtEmail = _document.GetElementByID("email");
    HtmlElement txtResult = _document.GetElementByID("emailValidationResult");

    // 엘리먼트의 값을 얻어와 정규 표현식으로 점검하고 결과 설정
    string email = txtEmail.GetAttribute("value");
    if (email == null)    // 값이 설정되지 않은 경우 null이 올 수 있으므로 주의
        email = "";
    Regex reg = new Regex(@"\w+[@]\w+\.\w+");
    if (reg.Match(email).Success)
    {
        txtResult.SetAttribute("value", " E-mail [" + email + "] .");
    }
    else
    {
        txtResult.SetAttribute("value", " E-mail [" + email + "] .");
    }
}

5. 프로젝트를 빌드하고 F5를 눌러 테스트 해봅니다.


호스트 HTML 페이지의 속성(Property) 참조
HtmlPage 클래스는 또한 현재 호스트 HTML 페이지의 유용한 속성을 제공합니다. 예제 2를 작성해 보겠습니다.
Howto:5-3 호스트 HTML 페이지의 속성 참조
1. 예제 2의 버튼 클릭 이벤트를 받아서 처리할 이벤트 핸들러를 선언합니다. 내부 코드는 아래에서 추가하도록 하고 여기에서는 단지 이름만을 선언해 놓습니다.
C#
private void OnPropertiesClicked(object sender, HtmlEventArgs e)
{
}

2. 클래스의 생성자에 HTML DOM 참조로부터 실제로 이벤트를 부여할 엘리먼트의 참조를 얻고 이벤트 핸들러를 지정하는 코드를 추가합니다.
C#
// 예제2의 버튼 ID를 통해 이벤트 핸들러 지정
HtmlElement btnProperties = _document.GetElementByID("propertiesSubmit");
btnProperties.AttachEvent("onclick", new EventHandler<HtmlEventArgs>(this.OnPropertiesClicked));

3. 이제 실제 작동할 이벤트 핸들러 코드를 작성합니다.
C#
private void OnPropertiesClicked(object sender, HtmlEventArgs e)
{
    // 엘리먼트의 참조 얻기

    HtmlElement txtProperties = _document.GetElementByID("properties");

    //
호스트 HTML 페이지의 속성들을 표시
    string
output = "";
    output = "절대 경로 : " + HtmlPage.DocumentUri.AbsolutePath;
    output += "\n플랫폼 : " + HtmlPage.BrowserInformation.Platform;
    output += "\n에이전트 : " + HtmlPage.BrowserInformation.UserAgent;
    txtProperties.SetAttribute("value", output);
}

4. 프로젝트를 빌드하고 F5를 눌러 테스트 해봅니다.

호스트 HTML DOM의 메소드 호출
HtmlPage 클래스는 또한 HTML DOM과 관계된 메소드를 제공합니다. 예제 3에서 지정된 URL로 이동하는 Navigate 메소드를 호출하는 예제를 작성해 보겠습니다.
Howto:5-4 호스트 HTML DOM의 메소드 호출
1. 예제 3의 버튼 클릭 이벤트를 받아서 처리할 이벤트 핸들러를 선언합니다. 내부 코드는 아래에서 추가하도록 하고 여기에서는 단지 이름만을 선언해 놓습니다.
C#
private void OnNavigateClicked(object sender, HtmlEventArgs e)
{
}

2. 클래스의 생성자에 HTML DOM 참조로부터 실제로 이벤트를 부여할 엘리먼트의 참조를 얻고 이벤트 핸들러를 지정하는 코드를 추가합니다.
C#
// 예제3의 버튼 ID를 통해 이벤트 핸들러 지정
HtmlElement btnNavigate = _document.GetElementByID("urlSubmit");
btnNavigate.AttachEvent("onclick", new EventHandler<HtmlEventArgs>(this.OnNavigateClicked));

3. 이제 실제 작동할 이벤트 핸들러 코드를 작성합니다.
C#
private void OnNavigateClicked(object sender, HtmlEventArgs e)
{
    // 엘리먼트의 참조 얻기
    HtmlElement txtUrl = _document.GetElementByID("url");

    // 엘리먼트의 값을 가져와 정규 표현식으로 점검하고 결과 설정
    string url = txtUrl.GetAttribute("value");
    if (url == null)
    url = "";

    // 먼저 스키마 지정(http://등등)이 없으면 http://를 추가
    Regex regPre = new Regex(@"([\w]+:)?//\w*");
    if (!regPre.Match(url).Success)
        url = "http://" + url;

    // 다시 검사(RFC URL규정)
    Regex reg = new Regex(@"(([\w]+:)?//)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?");
    if (reg.Match(url).Success)
    {
        HtmlPage.Navigate(url);
    }
    else
    {
        txtUrl.SetAttribute("value", " URL.");
    }
}

4. 프로젝트를 빌드하고 F5를 눌러 테스트 해봅니다.

예제 프로젝트를 첨부하였습니다.



디버깅 팁

예제와 같이 어떤 개체의 참조를 문자열로부터 얻는 코드는 대단히 위험합니다. 컴파일러는 코드를 빌드하는 시점에서는 그 문자열에 사소한 오타나 문제점이 있어도 그것을 감지할 수 없기 때문에 런타임에 예외를 발생시킬 가능성이 매우 높으며 따라서 반드시 try~catch 구문을 사용하여 문제가 발생할 경우 예외 처리를 수행해야 합니다.

예를 들어 초기에 HTML 페이지에 'test'라는 ID의 엘리먼트를 배치하고 페이지를 작성하였고 매니지드 코드에서 이 엘리먼트에 디버깅 결과를 출력하였다고 합시다. 시간이 흘러 더 이상 test가 필요 없게 되었고 페이지에서 이 엘리먼트를 삭제했지만 깜빡하고 매니지드 코드에서는 관련 코드를 제거하지 않았다면 해당 코드가 실행될 때 더 이상 test라는 ID를 가진 엘리먼트를 찾을 수 없으므로 Silverlight 애플리케이션은 예외를 발생시키고 그 이후의 어떤 코드도 실행되지 않게 될 것입니다.

항상 런타임에 동적으로 바인딩 되는 개체를 참조할 때에는 반드시 예외 처리를 할 것을 강력하게 권장합니다.

참고

Silverlight 공식 QuickStarts 참고:
http://silverlight.net/QuickStarts/Dom/DomAccess.aspx

.NET Framework의 정규표현식 참고:
http://msdn2.microsoft.com/ko-kr/library/hs600312(VS.80).aspx

정규표현식 라이브러리:
http://regexlib.com/
신고
Posted by gongdo


티스토리 툴바