expat은 아래와 같은 기본 코드로 작동된다. (링크 참조)
2010/03/23 - [프로그램 사용/expat / XML] - expat-2.0.1 example

문제는 위의 main() 함수에서 fread()를 이용하여 버퍼 사이즈 만큼 읽어오기 때문에
최악의 경우 데이터나 elemet가 잘리는 경우가 발생할수 있다는 것이다.
예를 들어

<entry gd:etag="W/"CUQFRX47eCp7ImA9WxFXF0s."">
    <id>tag:youtube.com,2008:video:qlZjYvHWTo4</id>
    <published>2010-05-19T07:13:31.000Z</published>
    <updated>2010-05-25T04:55:14.000Z</updated>
</entry>

이러한 XML이 있고, "id" 태그의 데이터를 읽으려고 할때 최악의 경우
버퍼의 경계에 걸릴경우,
tag:youtube.com,2008:vide
o:qlZjYvHWTo4
이런식으로 두번을 읽어 오게 된다.

일단은 버퍼를 늘리는 것 외에는 딱히 다른 방법은 찾지 못했다.

'프로그램 사용 > expat & XML' 카테고리의 다른 글

GPX TCX 포맷  (0) 2013.06.22
Javascript DOM API / XML  (2) 2010.07.13
expat으로 smi 자막파일 파싱은 불가?  (0) 2010.05.03
SAX (Simple API for XML)  (0) 2010.04.23
xml 트리 탐색 - XML tree navigation  (0) 2010.04.17
Posted by 구차니
smi 파일을 파싱할일이 생겨서 대충 훑어 보는데
아무리 봐도 열고닫기가 잘안되있어서 안될꺼 같았는데

의외로 엉뚱한 부분에서 진행이 안된다.

$ ./smi.o
not well-formed (invalid token) at line 9

<SAMI>
<HEAD>
<Title> Produced by CCMP produced by CineCaption </Title>
<STYLE TYPE="text/css">
<!--
P { margin-top:2pt; margin-bottom:2pt; margin-left:8pt; margin-right:8pt;
    text-align:center;
    font-size:20pt; font-family:arial, sans-serif; font-weight:normal; color:white; }
.KRCC { Name:한글; lang:ko-KR; SAMIType:CC;}
.ENCC { Name:영어; lang:en-US; SAMIType:CC;}
#STDPrn { Name:보통;}
#LargePrn { Name:크게; font-size:25pt;}
#SmallPrn { Name:작게; font-size:15pt;}
-->
</Style>

9 line은 .KRCC 라는 부분인데 시작부터 막히는구나.. ㅠ.ㅠ
Posted by 구차니
XML_SetCharacterDataHandler() 함수는 prototype에서 보이는 대로
XML_char *s, int len 두개의 변수를 이용한다.

즉, 이 함수를 통해 받아들여지는 내용을 출력하기 위해서는
printf("%s",s); 가 아닌

for (int i = 0; i < len; i++) printf("%c",s[i]);
로 한글자씩 len에 맞게 출력을 해주어야 한다.

XML_SetCharacterDataHandler(XML_Parser p, XML_CharacterDataHandler charhndl)

typedef void (*XML_CharacterDataHandler)(void *userData, const XML_Char *s, int len);

Set a text handler. The string your handler receives is NOT zero terminated. You have to use the length argument to deal with the end of the string. A single block of contiguous text free of markup may still result in a sequence of calls to this handler. In other words, if you're searching for a pattern in the text, it may be split across calls to this handler.

[링크 : http://www.xml.com/pub/a/1999/09/expat/index.html?page=3#chardatahandler]

<media:description type='plain'>The funniest 6 minutes you will ever see! Remember how many of these you have done! Follow @ http://www.twitter.com/judsonlaipply Check my book out at http://www.mightaswelldance.com
http://www.theevolutionofdance.com -
for more info including song list!</media:description>

                        <media:description type="plain">
========== [4]
The funniest 6 minutes you will ever see! Remember how many of these you have done! Follow @ http://www.twitter.com/judsonlaipply Ch
eck my book out at http://www.mightaswelldance.com
========== [4]


========== [4]
http://www.theevolutionofdance.com -
========== [4]


========== [4]
for more info including song list!
                        </media:description>

그리고, 위에 보이듯이, 줄단위로 받아들이므로
단순하게 한번 복사하는 걸로는 충분하지 않아 보인다.(어떻게 할지 모호하면.. realloc 해주어야 하나..)

'프로그램 사용 > expat & XML' 카테고리의 다른 글

SAX (Simple API for XML)  (0) 2010.04.23
xml 트리 탐색 - XML tree navigation  (0) 2010.04.17
&amp; &lt; &gt; &quot; 는 머지?  (0) 2010.03.31
expat '간략한' 사용법  (0) 2010.03.28
expat-2.0.1 example  (11) 2010.03.23
Posted by 구차니
expat xml 파서를 이용해서 xml을 구조화시키는(간단하게 탭정렬) 것을 하다보니, data 부분에서 파싱에러가 발생한다.
URL 등에서 &가 &amp; 로 변환되지 않았다고
"세미콜론이(;)이 와야 합니다." 라는 문법오류가 발생한다.

아무튼 expat의 기본샘플 프로그램(?)인
xmlwf.c의 내용을  보니 별도로 이러한 특수문자를 처리하는 함수가 있었다.

static void XMLCALL
characterData(void *userData, const XML_Char *s, int len)
{
  FILE *fp = (FILE *)userData;
  for (; len > 0; --len, ++s) {
    switch (*s) {
    case T('&'):
      fputts(T("&"), fp);
      break;
    case T('<'):
      fputts(T("<"), fp);
      break;
    case T('>'):
      fputts(T(">"), fp);
      break;
#ifdef W3C14N
    case 13:
      fputts(T("&#xD;"), fp);
      break;
#else
    case T('"'):
      fputts(T("""), fp);
      break;
    case 9:
    case 10:
    case 13:
      ftprintf(fp, T("&#%d;"), *s);
      break;
#endif
    default:
      puttc(*s, fp);
      break;
    }
  }
}

아무튼, 많이 보던 녀석인데 도대체 어떤 표준인지 알수가 없는데,
검색하다 보니 iso8859-1 인것 같기도 하고.. 구분이 모호하다.
아무튼, XHTML/HTML에서 사용되는 방식인듯 하다.

Reserved Characters in HTML

Some characters are reserved in HTML and XHTML. For example, you cannot use the greater than or less than signs within your text because the browser could mistake them for markup.

HTML and XHTML processors must support the five special characters listed in the table below:

Character Entity Number Entity Name Description
" &#34; &quot; quotation mark
' &#39; &apos; (does not work in IE) apostrophe 
& &#38; &amp; ampersand
< &#60; &lt; less-than
> &#62; &gt; greater-than
Note: Entity names are case sensitive!

[링크 : http://www.w3schools.com/tags/ref_entities.asp]
[링크 : http://microweb.textcube.com/31]

'프로그램 사용 > expat & XML' 카테고리의 다른 글

xml 트리 탐색 - XML tree navigation  (0) 2010.04.17
expat XML_SetCharacterDataHandler() function  (0) 2010.04.09
expat '간략한' 사용법  (0) 2010.03.28
expat-2.0.1 example  (11) 2010.03.23
expat  (4) 2010.03.21
Posted by 구차니
expat은 handler를 기반으로 작동한다.
특정 이벤트에 작동하는 핸들러를 등록하여 그 값을 뺴내는데
이벤트(?)는 아래의 SetHandler 함수로 등록을 한다.

StartElement는 <tag>
EndElement는 </tag> 에
대해서 값을 받아 오도록 한다.

[링크 : http://www.hpc.wm.edu/SciClone/documentation/software/misc/expat/reference.html]

머.. 일단 실행은 해보고 -ㅁ-?
Start와 End는 확실한데.. 다른건 좀 일단 실험을... ㅠ.ㅠ

XML_SetElementHandler 는 XML_SetStartElementHandler 보다 우선하고,
static void XMLCALL ElementHandler (void *userData, const XML_Char *name, const XML_Char **atts)
에서 name은 XML_SetStartElementHandler 에서 리턴하는 것과 같고
atts는 몇 개인지 알수는 없으므로  atts[idx] != NULL 일때 까지 돌리는수 밖에 없다.

원본데이터
<ns0:feed xmlns:ns00="http://www.w3.org/2005/Atom">

결과물
name[ns0:feed]
atts[xmlns:ns0] atts[http://www.w3.org/2005/Atom]

atts[idx]

'프로그램 사용 > expat & XML' 카테고리의 다른 글

xml 트리 탐색 - XML tree navigation  (0) 2010.04.17
expat XML_SetCharacterDataHandler() function  (0) 2010.04.09
&amp; &lt; &gt; &quot; 는 머지?  (0) 2010.03.31
expat-2.0.1 example  (11) 2010.03.23
expat  (4) 2010.03.21
Posted by 구차니
expat-2.0.1 에 포함되어있는 예제파일인
elements.c를 약간 변형하여

XML tag로 출력되도록 약간 수정하였다.
컴파일에 필요한 libexpat.lib 파일과 expat.h 파일
그리고 테스트용 XML 파일(youtube page)가 포함되어있다.
(libexpat.lib는 내부적으로 libexpat.dll을 호출하는 것으로 보인다.)



/* This is simple demonstration of how to use expat. This program
reads an XML document from standard input and writes a line with
the name of each element to standard output indenting child
elements by one tab stop more than their parent element.
It must be used with Expat compiled for UTF-8 output.
*/

#include "stdio.h"
#include "expat.h"

#if defined(__amigaos__) && defined(__USE_INLINE__)
#include "proto/expat.h"
#endif

#ifdef XML_LARGE_SIZE
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
#define XML_FMT_INT_MOD "I64"
#else
#define XML_FMT_INT_MOD "ll"
#endif
#else
#define XML_FMT_INT_MOD "l"
#endif

static void XMLCALL
startElement(void *userData, const char *name, const char **atts)
{
	int i;
	int *depthPtr = (int *)userData;
	for (i = 0; i < *depthPtr; i++)
		putchar('\t');
	printf("<%s>\n",name);
//	puts(name);
	*depthPtr += 1;
}

static void XMLCALL
endElement(void *userData, const char *name)
{
	int i;
	int *depthPtr = (int *)userData;
	*depthPtr -= 1;
	for (i = 0; i < *depthPtr; i++)
		putchar('\t');
	printf("</%s>\n",name);
	//	puts(name);
}

int
main(int argc, char *argv[])
{
	FILE *fp;
	char buf[BUFSIZ];
	XML_Parser parser = XML_ParserCreate(NULL);
	int done;
	int depth = 0;
	
	fp = fopen("GetRecentlyFeaturedVideoFeed.xml","r");
	
	XML_SetUserData(parser, &depth);
	XML_SetElementHandler(parser, startElement, endElement);
	do {
		int len = (int)fread(buf, 1, sizeof(buf), fp);
		done = len < sizeof(buf);
		if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) {
			fprintf(stderr,
				"%s at line %" XML_FMT_INT_MOD "u\n",
				XML_ErrorString(XML_GetErrorCode(parser)),
				XML_GetCurrentLineNumber(parser));
			return 1;
		}
	} while (!done);
	XML_ParserFree(parser);
	fclose(fp);
	return 0;
}

'프로그램 사용 > expat & XML' 카테고리의 다른 글

xml 트리 탐색 - XML tree navigation  (0) 2010.04.17
expat XML_SetCharacterDataHandler() function  (0) 2010.04.09
&amp; &lt; &gt; &quot; 는 머지?  (0) 2010.03.31
expat '간략한' 사용법  (0) 2010.03.28
expat  (4) 2010.03.21
Posted by 구차니
expat은 c언어로 작성된 XML 파서이다.
음.. c라고는 하지만, python 2.6 에서는 expat을 기본 XML 파서로 내장한다.

아래는 expat 홈페이지와, c에서 expat을 사용하는 예제들이 들어있다.
링크만 발견하고 실제로 사용해보진 못했지만,
handler역활을 하는 함수를 추가하여,
그 함수들을 태그의 시작이나 끝 그리고 데이터 부분에서 호출하게 되는것으로 보인다.

[링크 : http://expat.sourceforge.net/]
    [링크 : http://www.vivtek.com/xmltools/]
    [링크 : http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/XML/expat_xml]

python2.6의 expat 예제
실제로 windows에서 2.6으로 돌려보니 결과가 조금 다르게 나왔다.
원래 문서에는 출력된 문자열 앞에 u가 붙어있지 않다.(unicode 문자열을 알리는 접두?)
>>> p.Parse("""<?xml version="1.0"?>
... <parent id="top"><child1 name="paul">Text goes here</child1>
... <child2 name="fred">More text</child2>
... </parent>""", 1)
Start element: parent {u'id': u'top'}
Start element: child1 {u'name': u'paul'}
Character data: u'Text goes here'
End element: child1
Character data: u'\n'
Start element: child2 {u'name': u'fred'}
Character data: u'More text'
End element: child2
Character data: u'\n'
End element: parent
1

[링크 : http://docs.python.org/library/pyexpat.html]

'프로그램 사용 > expat & XML' 카테고리의 다른 글

xml 트리 탐색 - XML tree navigation  (0) 2010.04.17
expat XML_SetCharacterDataHandler() function  (0) 2010.04.09
&amp; &lt; &gt; &quot; 는 머지?  (0) 2010.03.31
expat '간략한' 사용법  (0) 2010.03.28
expat-2.0.1 example  (11) 2010.03.23
Posted by 구차니