제공: 한빛 네트워크
저자: Paul Sobocinski, 이대엽 역
원문: RSS and AJAX: A Simple News Reader
| 나름대로 개념정의 XML -> Mark Up language이다. html과는 달리 스크립트이기 보다 DATABASE의 성격이 강하다. Well-formed XML -> XML로써 정의되기위한 기본구성조건 DTD -> document type definition 의 약자로 문서원형 정의라 할수있다 XSL -> XML 와 프리젠테이션 문서간 변형 역할 DOM -> Document Object Model DOM은 HTML과 XML 문서를 연결시켜주는 프로그래밍적 인터페이스 SAX -> simple api for xml 웹파일들을 해석할수 있게 해주는 응용프로그램 인터페이스 XQL -> 저장매체로써 XML XML_RSS -> Really Simple Syndication의약자로 xml를 이용한 콘텐츠 정보를 교환 목적으로 된 규약 XML_RPC -> remote procedure call 의 약자로 다른언어로 작성된 프고르램이 스로세스를 공유하면서 수행되도록 구성된것 SOAP -> Simple Object Access Protocol xml 이용 통신규약? WSDL -> 웹서비스에서 제공하는 것들에 대한 정보 및 기타 등등 이 있는 문서 AJAX -> XMLHttpRequest 객체를 이용한 자바스크립트 class XMLHttpRequest -> 브라우저가 웹서버와 통신하기 위한 컴포넌트. MSXML.DOMDocument -> MS에서 제공하는 DOM 객체 컴포넌트. 개념잡기 참조 사이트 XML의 구조와 문법 http://blog.naver.com/pciswife?Redirect=Log&logNo=100020781686 Well-formed XML http://blog.naver.com/swinter8?Redirect=Log&logNo=130000715517 RSS 란 http://blog.empas.com/apple8856/list.html?p=2 XML DOM 초보자를 위한 가이드 http://blog.naver.com/BlogMain.nhn?blogId=ncs74&Redirect=Dlog&Qs=/ncs74/90000341312 간단한 RSS 리더 구현 (ASP) http://blog.naver.com/harkbart?Redirect=Log&logNo=20329936 SOAP의 Attachment 기능을 이용한 이기종간 파일 전송-5 http://blog.naver.com/harry5313?Redirect=Log&logNo=50000779862 ASP 와 XML http://blog.naver.com/multist?Redirect=Log&logNo=7761684 XMLHttpRequest 기본문법 http://blog.naver.com/nhsbs?Redirect=Log&logNo=130001581285 SOAP Format http://cafe.naver.com/infonuri.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=7 XMLHTTP 예제 http://jibbering.com/2002/4/httprequest.html XMLHttpRequest http://kb.mozillazine.org/XMLHttpRequest MSDN XML http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmsxml/html/msxmlcabfile.asp IBM XML http://www-128.ibm.com/developerworks/kr/xml/ 매우도움됨 객체 reference http://www.xulplanet.com/references/xpcomref/ifaces/nsIXMLHttpRequest.html AJAX 프로그래밍 with .NET http://blog.naver.com/ez4ez?Redirect=Log&logNo=20292120 |

<html>
<head>
<!--B-->
<script language="javascript" src="rssajax6.js"></script>
<!--C-->
<style type="text/css">
#chan_items { margin: 20px; }
#chan_items #item { margin-bottom: 10px; }
#chan_items #item #item_title { font-weight: bold; }
</style>
</head>
<body>
<!--A-->
<form name="rssform" onsubmit="getRSS(); return false;">
<select name="rssurl">
<option value="test-rss.xml">test RSS feed</option>
<option value="google-rss.xml">google RSS feed</option>
</select>
<input type="submit" value="fetch rss feed" />
</form>
<div id="chan">
<div id="chan_title"></div>
<div id="chan_link"></div>
<div id="chan_description"></div>
<a id="chan_image_link" href=""></a>
<div id="chan_items"></div>
<div id="chan_pubDate"></div>
<div id="chan_copyright"></div>
</div>
</body>
</html>
이제 나머지 대부분의 HTML 코드는 무시하기로 하고 <!-A-->로 표시되어 있는 폼 엘리먼트에 집중하기로 하자. RSS XML 파일의 이름은 select 엘리먼트의 option 태그의 value 속성으로 지정되어 있다. 사용자가 이러한 파일 가운데 하나를 선택하고 나면 폼이 전송된다. 전체 과정을 시작시키는 자바스크립트가 onsubmit 태그에 있는 것을 볼 수 있다. 자바스크립트 함수가 호출된 다음 폼 전체가 서버로 "틀에 박힌" 방식대로 전달되는 것을 막기 위해 false를 리턴하도록 return false 문장을 추가하였다. 만약 return false 문장을 생략했다면 전체 페이지가 갱신되면서 Ajax를 이용하여 읽어왔던 모든 데이터를 잃어버리게 될 것이다. 마지막으로 남은 하나는 <!-B-->로 표시된 부분에서 분리되어 있는 파일을 참조하도록 자바스크립트 코드가 헤더 부분에 포함되어 있다는 것이다. 여러분이 의아해 할 경우를 대비해서 설명하는 것이지만 <!-C-->로 표시된 부분에서 <style> 태그의 내용은 브라우저에게 showRSS(RSS) 함수에 의해 RSS 데이터가 HTML 페이지에 쓰여졌을 때 어떻게 보여주어야 하는지를 나타내는 것이다. function getRSS()
{
/*A*/
if (window.ActiveXObject) //IE
xhr = new ActiveXObject("Microsoft.XMLHTTP");
else if (window.XMLHttpRequest) //other
xhr = new XMLHttpRequest();
else
alert("your browser does not support AJAX");
/*B*/
xhr.open("GET",document.rssform.rssurl.value,true);
/*C*/
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("Pragma", "no-cache");
/*D*/
xhr.onreadystatechange = function() {
if (xhr.readyState == 4)
{
if (xhr.status == 200)
{
/*F*/
if (xhr.responseText != null)
processRSS(xhr.responseXML);
else
{
alert("Failed to receive RSS file from the server - file not found.");
return false;
}
}
else
alert("Error code " + xhr.status + " received: " + xhr.statusText);
}
}
/*E*/
xhr.send(null);
}
이 함수를 단계별로 훑어보면서 그것이 무엇을 하는지 생각해 보자. 코드내에 포함되어 있는 레이블은 아래의 대응되는 설명을 가리킨다. function processRSS(rssxml)
{
RSS = new RSS2Channel(rssxml);
showRSS(RSS);
}
이 함수는 단순히 RSS2Channel 객체의 생성자를 호출하고 rssxml을 전달한다. 이 인자는 특별한 의미를 지니고 있는데, 그것은 모든 RSS 정보를 포함한다는 것이다. 게다가 자바스크립트는 이것을 XML 객체로서 인식할 수 있으며, 따라서 자바스크립트에 내장된 DOM(문서 객체 모델; Document Object Model)의 함수와 속성을 그것에 사용할 수 있다. 이는 서버의 응답을 받기 위하여 XHR 객체의 속성인 responseXML을 사용하였으므로 이러한 작업이 가능하다. 만약 responseText를 사용하였다면 XML을 파싱하는 것은 훨씬 더 어려워질지도 모른다.. function RSS2Channel(rssxml)
{
/*A*/
/*required string properties*/
this.title;
this.link;
this.description;
/*optional string properties*/
this.language;
this.copyright;
this.managingEditor;
this.webMaster;
this.pubDate;
this.lastBuildDate;
this.generator;
this.docs;
this.ttl;
this.rating;
/*optional object properties*/
this.category;
this.image;
/*array of RSS2Item objects*/
this.items = new Array();
/*B*/
var chanElement = rssxml.getElementsByTagName("channel")[0];
var itemElements = rssxml.getElementsByTagName("item");
/*C*/
for (var i=0; i<itemElements.length; i++)
{
Item = new RSS2Item(itemElements[i]);
this.items.push(Item);
}
/*D*/
var properties = new Array("title", "link", "description",
"language", "copyright", "managingEditor", "webMaster",
"pubDate", "lastBuildDate", "generator", "docs", "ttl", "rating");
var tmpElement = null;
for (var i=0; i<properties.length; i++)
{
tmpElement = chanElement.getElementsByTagName(properties[i])[0];
if (tmpElement!= null)
eval("this."+properties[i]+"=tmpElement.childNodes[0].nodeValue");
}
/*E*/
this.category = new RSS2Category(chanElement.getElementsByTagName("category")[0]);
this.image = new RSS2Image(chanElement.getElementsByTagName("image")[0]);
}
시작하기에 앞서 코드들을 좀 더 작은 조각으로 쪼갠 다음 각각의 것들을 하나씩 설명할 것이다. function RSS2Category(catElement)
{
if (catElement == null) {
this.domain = null;
this.value = null;
} else {
this.domain = catElement.getAttribute("domain");
this.value = catElement.childNodes[0].nodeValue;
}
}
이 객체는 두 개의 속성(domain과 value)을 가진 단순한 객체이다. value 속성은 XML 태그의 실질적인 내용을 포함하는데 반해, domain 속성은 XML domain 태그 속성의 내용이 설정된다. 예를 들어, 일반적인 category XML 엘리먼트의 모습은 다음과 같다: <category domain="Syndic8">1785</category>. 이 경우 this.domain의 값은 Syndic8이 되며 this.value의 값은 1785가 된다. XML 태그로부터 domain 속성을 구하기 위해 getAttribute() 함수를 이용하여 파라미터로서(이 경우, domain) 읽어오기를 원하는 태그의 속성을 전달한다. function RSS2Image(imgElement)
{
if (imgElement == null) {
this.url = null;
this.link = null;
this.width = null;
this.height = null;
this.description = null;
} else {
imgAttribs = new Array("url","title","link","width","height","description");
for (var i=0; i<imgAttribs.length; i++)
if (imgElement.getAttribute(imgAttribs[i]) != null)
eval("this."+imgAttribs[i]+"=imgElement.getAttribute("+imgAttribs[i]+")");
}
}
이제 RSS2Channel 객체에 남아있는 마지막 속성인 items에 대해 알아볼 것인데, items는 RSS2Item 객체들의 배열을 포함하고 있다. 이 객체의 코드가 아래에 나타나 있다:function RSS2Item(itemxml)
{
/*A*/
/*required properties (strings)*/
this.title;
this.link;
this.description;
/*optional properties (strings)*/
this.author;
this.comments;
this.pubDate;
/*optional properties (objects)*/
this.category;
this.enclosure;
this.guid;
this.source;
/*B*/
var properties = new Array("title", "link", "description", "author", "comments", "pubDate");
var tmpElement = null;
for (var i=0; i<properties.length; i++)
{
tmpElement = itemxml.getElementsByTagName(properties[i])[0];
if (tmpElement != null)
eval("this."+properties[i]+"=tmpElement.childNodes[0].nodeValue");
}
/*C*/
this.category = new RSS2Category(itemxml.getElementsByTagName("category")[0]);
this.enclosure = new RSS2Enclosure(itemxml.getElementsByTagName("enclosure")[0]);
this.guid = new RSS2Guid(itemxml.getElementsByTagName("guid")[0]);
this.source = new RSS2Source(itemxml.getElementsByTagName("source")[0]);
}
RSS2Item 객체는 RSS2Channel과 여러모로 비슷하다. 먼저 얻어오게 될 속성을 나열하는 것으로부터 시작한다(A). 그런 다음 문자열 속성들을 순환하여 관련된 XML 태그의 내용을 각각 할당한다(B). 마지막으로 적절한 사용자 정의 객체의 생성자를 호출하여 객체의 속성을 설정하는데, 각 경우에 대응되는 데이터를 포함하고 있는 XML 엘리먼트를 전달한다. function RSS2Enclosure(encElement)
{
if (encElement == null) {
this.url = null;
this.length = null;
this.type = null;
} else {
this.url = encElement.getAttribute("url");
this.length = encElement.getAttribute("length");
this.type = encElement.getAttribute("type");
}
}
function RSS2Guid(guidElement)
{
if (guidElement == null) {
this.isPermaLink = null;
this.value = null;
} else {
this.isPermaLink = guidElement.getAttribute("isPermaLink");
this.value = guidElement.childNodes[0].nodeValue;
}
}
function RSS2Source(souElement)
{
if (souElement == null) {
this.url = null;
this.value = null;
} else {
this.url = souElement.getAttribute("url");
this.value = souElement.childNodes[0].nodeValue;
}
}
이제 RSS 객체를 완전하게 정의하였으므로 마지막 과정으로 옮겨갈 수 있는데, 마지막 과정은 객체의 실제 내용을 보여주는 것이다. <div class="rss" id="chan">
<div class="rss" id="chan_title"></div>
<div class="rss" id="chan_link"></div>
<div class="rss" id="chan_description"></div>
<a class="rss" id="chan_image_link" href=""></a>
<div class="rss" id="chan_items"></div>
<div class="rss" id="chan_pubDate"></div>
<div class="rss" id="chan_copyright"></div>
</div>
코드에서 볼 수 있듯이, 루트 div 엘리먼트는 여러 개의 자식 div 태그들을 가지고 있다. 이 태그들은 아래에 나타나 있는 showRSS(RSS) 함수에 의해 RSS 객체안의 데이터들을 보여줄 것이다.function showRSS(RSS)
{
/*A*/
var imageTag = "<img id='chan_image'";
var startItemTag = "<div id='item'>";
var startTitle = "<div id='item_title'>";
var startLink = "<div id='item_link'>";
var startDescription = "<div id='item_description'>";
var endTag = "</div>";
/*B*/
var properties = new Array("title","link","description","pubDate","copyright");
for (var i=0; i<properties.length; i++)
{
eval("document.getElementById('chan_"+properties[i]+"').innerHTML = ''"); /*B1*/
curProp = eval("RSS."+properties[i]);
if (curProp != null)
eval("document.getElementById('chan_"+properties[i]+"').innerHTML = curProp"); /*B2*/
}
/*C*/
/*show the image*/
document.getElementById("chan_image_link").innerHTML = "";
if (RSS.image.src != null)
{
document.getElementById("chan_image_link").href = RSS.image.link; /*C1*/
document.getElementById("chan_image_link").innerHTML = imageTag
+" alt='"+RSS.image.description
+"' width='"+RSS.image.width
+"' height='"+RSS.image.height
+"' src='"+RSS.image.url
+"' "+"/>"; /*C2*/
}
/*D*/
document.getElementById("chan_items").innerHTML = "";
for (var i=0; i<RSS.items.length; i++)
{
item_html = startItemTag;
item_html += (RSS.items[i].title == null) ? "" :
startTitle + RSS.items[i].title + endTag;
item_html += (RSS.items[i].link == null) ? "" :
startLink + RSS.items[i].link + endTag;
item_html += (RSS.items[i].description == null) ? "" :
startDescription + RSS.items[i].description + endTag;
item_html += endTag;
document.getElementById("chan_items").innerHTML += item_html; /*D1*/
}
return true;
}
A: RSS 피드안의 channel 항목의 개수를 알 길이 없으므로 그러한 RSS 항목을 위해 동적으로 HTML을 생성해야 한다. 이것들은 RSS2Item 데이터를 포함하게 될 HTML 태그의 기본값들이다. 또한 호환성을 위해 img HTML태그를 동적으로 생성할 것이다. 출처 : 한빛미디어
| 제목이 왜? 저런대여? 글 만드는거는 전혀 그렇습니다. 제가 말도 잘 조리있게 못해서 직접 누굴 만나서 대화하면 당신이 무슨 그런걸 할줄 아냐? 오해를 불러오기 딱좋은 글 솜씨와 말 주변 입니다. 실제로 저와 아주 가까운 사람이 눈꼽만큼 아는걸 수레바퀴 만큼 아는척 한다고 해서 그냥 속으로 당신이 믿던 말던 개의치 않고 그랬더랬습니다. 매일 공부를 게을리 하지않는다 이 생각은 숨넘어 가는날 까지 라는 제 사고는 고쳐지지 않는 순악질 ㅋㅋ 두뇌입니다. 아래에 RSS News Ticker 만드는 방법 입니다. 혹시 RSS Feed에 엠파스 블로그 공지글을 샘플로 붙여 봤는데, 혹시 이글이 블로그 운영에 적법치 안으면 이글을 삭제해 주셔도 좋습니다. 블로그 운영자님이 저의 게시판에 iframe 사용을 부여해 ㅋㅋ 주시면 참 좋을듯 한데 바로 보여 드리지 못하고 링크를 거는수 밖에 없군요.. 그럼 본문 입니다. // AJAX 뉴스티커 만들기. 개인 컴퓨터에서 RSS feed용 프로그램 다운받아 보는 그런것이 아니고 제가 올려 드리는건 웹 사이트 운영하시는 분이 자신의 사이트에 만들어 붙여서 보는 RSS feed 입니다. 참고로 저는 엠파스 블로그 운영자님의 새로운 글을 붙여봤구요.. 그리고 kbs 한국방송 공사 에서 RSS 뉴스 서비스를 하는데, 여기 뉴스를 리더로 읽어 들여보니 흥미롭습니다. RSS리더 프로그램으로 영업을 한다거나 하면 저의 글이 무색해 질겁니다. 비영리를 목적으로 순수히 공부와 개인 사이트의 발전을 위함이면 좋겠습니다. 그리고 저의 여기 블로그 RSS를 붙였습니다. 만드는법은 제가 일이 많아 간략히 올려 드립니다. 따로 첨부파일 안붙혀 드리는건 가만히 그냥 만들어 준거 다운 받기보다 직접 해보셔야 실력이 늘겁니다. 저의 포샵 수준이 바닥이라 이해를 하시고 봐주세요 ^^ 1. Ajax 뉴스 티커를 만들려면 우선 아래 링크에서 필요한 자스와 로딩 이미지를 다운 받습니다. 다운이라기 보다 복사해 오시면 되겠죠. 그리고 이걸 동작 시키기 위해서는 구글 API 키를 만듭니다. 아래에서.. 2.구글 API 키를 우선 만듭니다. 아래 링크에서 3. 1번항에서 만든 자스 혹은 html 페이지를 열어보시면 news feed 그리고 우측에 뉴스 로딩 페이지 xml주소가 여러분이 넣고싶은 주소를 넣으시면 동작이 멋지게 될겁니다. 제가 요즘 시간이 너무 나지않아 자세하게 설명을 못하여 드립니다. 오늘도 좋은하루 되세요 ^^ |