"xml.parsers.expat" --- Expat을 사용한 빠른 XML 구문 분석
*********************************************************

======================================================================

참고:

  If you need to parse untrusted or unauthenticated data, see XML
  security.

"xml.parsers.expat" 모듈은 Expat 유효성 검사 없는(non-validating) XML
구문 분석기에 대한 파이썬 인터페이스입니다. 이 모듈은 XML 구문 분석기
의 현재 상태를 나타내는 단일 확장형 "xmlparser"를 제공합니다.
"xmlparser" 객체가 만들어진 후, 객체의 다양한 어트리뷰트를 처리기 함수
로 설정할 수 있습니다. 그런 다음 XML 문서가 구문 분석기에 공급되면,
XML 문서에 있는 문자 데이터와 마크업에 대해 처리기 함수가 호출됩니다.

이 모듈은 "pyexpat" 모듈을 사용하여 Expat 구문 분석기에 대한 액세스를
제공합니다. "pyexpat" 모듈의 직접적인 사용은 폐지되었습니다.

이 모듈은 하나의 예외와 하나의 형 객체를 제공합니다:

exception xml.parsers.expat.ExpatError

   Expat이 에러를 보고할 때 발생하는 예외. Expat 에러 해석에 대한 자세
   한 정보는 섹션 ExpatError 예외를 참조하십시오.

exception xml.parsers.expat.error

   "ExpatError"의 별칭.

xml.parsers.expat.XMLParserType

   "ParserCreate()" 함수의 반환 값의 형.

"xml.parsers.expat" 모듈에는 두 가지 함수가 있습니다:

xml.parsers.expat.ErrorString(errno)

   주어진 에러 번호 *errno*에 대한 설명 문자열을 반환합니다.

xml.parsers.expat.ParserCreate(encoding=None, namespace_separator=None)

   새로운 "xmlparser" 객체를 만들고 반환합니다. 지정되면, *encoding*은
   XML 데이터가 사용하는 인코딩의 이름을 지정하는 문자열이어야 합니다.
   Expat은 파이썬만큼 많은 인코딩을 지원하지 않으며, 인코딩 레퍼토리를
   확장할 수 없습니다; UTF-8, UTF-16, ISO-8859-1 (Latin1) 및 ASCII를
   지원합니다. *encoding* [1] 이 제공되면 문서의 묵시적이나 명시적 인
   코딩을 대체합니다.

   Expat은 XML 이름 공간 처리를 선택적으로 수행할 수 있는데,
   *namespace_separator*에 값을 제공하는 것으로 활성화됩니다. 값은 한
   문자 문자열이어야 합니다; 문자열의 길이가 잘못되면 "ValueError"가
   발생합니다 ("None"은 생략과 같은 것으로 간주합니다). 이름 공간 처리
   가 활성화되면, 이름 공간에 속하는 엘리먼트 형 이름과 어트리뷰트 이
   름이 확장됩니다. 엘리먼트 처리기 "StartElementHandler"와
   "EndElementHandler" 에 전달된 엘리먼트 이름은 이름 공간 URI, 이름
   공간 구분 문자 및 이름의 로컬 부분의 이어붙이기입니다. 이름 공간 구
   분자가 0바이트("chr(0)")이면 이름 공간 URI와 로컬 부분이 구분자 없
   이 연결됩니다.

   예를 들어, *namespace_separator*가 스페이스 문자("' '")로 설정되고
   다음 문서가 구문 분석되면:

      <?xml version="1.0"?>
      <root xmlns    = "http://default-namespace.org/"
            xmlns:py = "http://www.python.org/ns/">
        <py:elem1 />
        <elem2 xmlns="" />
      </root>

   "StartElementHandler"는 각 엘리먼트에 대해 다음 문자열을 수신합니다
   :

      http://default-namespace.org/ root
      http://www.python.org/ns/ elem1
      elem2

   "pyexpat"에서 사용하는 "Expat" 라이브러리의 제한으로 인해, 반환된
   "xmlparser" 인스턴스는 단일 XML 문서를 구문 분석하는 데만 사용할 수
   있습니다. 고유한 구문 분석기 인스턴스를 제공하려면 문서마다
   "ParserCreate"를 호출하십시오.

더 보기:

  Expat XML 구문 분석기
     Expat 프로젝트의 홈페이지.


XMLParser 객체
==============

"xmlparser" 객체에는 다음과 같은 메서드가 있습니다:

xmlparser.Parse(data[, isfinal])

   문자열 *data*의 내용을 구문 분석하고, 구문 분석된 데이터를 처리하기
   위해 적절한 처리기 함수를 호출합니다. 이 메서드에 대한 최종 호출에
   서 *isfinal*은 참이어야 합니다; 여러 파일을 제출하는 것이 아니라,
   단일 파일을 여러 조각으로 나누어 구문 분석 할 수 있도록 합니다.
   *data*는 언제든지 빈 문자열이 될 수 있습니다.

xmlparser.ParseFile(file)

   *file* 객체에서 읽은 XML 데이터를 구문 분석합니다. *file*은 더는 데
   이터가 없을 때 빈 문자열을 반환하는 "read(nbytes)" 메서드만 제공하
   면 됩니다.

xmlparser.SetBase(base)

   선언에서 시스템 식별자에 있는 상대 URI를 결정하는 데 사용할 베이스
   를 설정합니다. 상대 식별자 결정은 응용 프로그램에 맡겨집니다: 이 값
   은 *base* 인자로 "ExternalEntityRefHandler()",
   "NotationDeclHandler()" 및 "UnparsedEntityDeclHandler()" 함수에 전
   달됩니다.

xmlparser.GetBase()

   "SetBase()"에 대한 이전 호출에 의해 설정된 베이스를 포함하는 문자열
   을 반환하거나, "SetBase()"가 호출되지 않았으면 "None"을 반환합니다.

xmlparser.GetInputContext()

   현재 이벤트를 생성한 입력 데이터를 문자열로 반환합니다. 데이터는 텍
   스트를 포함하는 엔티티의 인코딩을 따릅니다. 이벤트 처리기가 활성화
   되지 않은 상태에서 호출될 때, 반환 값은 "None"입니다.

xmlparser.ExternalEntityParserCreate(context[, encoding])

   부모 구문 분석기가 구문 분석한 내용이 참조하는 외부 구문 분석된 엔
   티티를 구문 분석하는 데 사용할 수 있는 "자식" 구문 분석기를 만듭니
   다. *context* 매개 변수는 아래 설명된 "ExternalEntityRefHandler()"
   처리기 함수에 전달된 문자열이어야 합니다. 자식 구문 분석기는
   "ordered_attributes"와 "specified_attributes"가 이 구문 분석기의 값
   으로 설정된 상태로 만들어집니다.

xmlparser.SetParamEntityParsing(flag)

   매개 변수 엔티티(외부 DTD 부분 집합을 포함합니다)의 구문 분석을 제
   어합니다. 가능한 *flag* 값은 "XML_PARAM_ENTITY_PARSING_NEVER",
   "XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE" 및
   "XML_PARAM_ENTITY_PARSING_ALWAYS"입니다. 플래그 설정에 성공하면 참
   을 반환합니다.

xmlparser.UseForeignDTD([flag])

   *flag*에 대해 참값(기본값)으로 이를 호출하면 Expat이 대체 DTD를 로
   드할 수 있도록 모든 인자를 "None"으로 "ExternalEntityRefHandler"를
   호출하도록 합니다. 문서에 문서 형 선언이 포함되어 있지 않으면,
   "ExternalEntityRefHandler"는 여전히 호출되지만,
   "StartDoctypeDeclHandler"와 "EndDoctypeDeclHandler"는 호출되지 않습
   니다.

   *flag*에 대해 거짓 값을 전달하면 참값을 전달한 이전 호출이 취소되지
   만, 그렇지 않으면 효과가 없습니다.

   이 메서드는 "Parse()"나 "ParseFile()" 메서드가 호출되기 전에만 호출
   할 수 있습니다; 이들 중 어느 것이라도 호출된 후에 호출하면 "code"
   어트리뷰트가
   "errors.codes[errors.XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING]"로
   설정된 "ExpatError"가 발생합니다.

xmlparser.SetReparseDeferralEnabled(enabled)

   경고:

     Calling "SetReparseDeferralEnabled(False)" has security
     implications, as detailed below; please make sure to understand
     these consequences prior to using the "SetReparseDeferralEnabled"
     method.

   Expat 2.6.0 introduced a security mechanism called "reparse
   deferral" where instead of causing denial of service through
   quadratic runtime from reparsing large tokens, reparsing of
   unfinished tokens is now delayed by default until a sufficient
   amount of input is reached. Due to this delay, registered handlers
   may — depending of the sizing of input chunks pushed to Expat — no
   longer be called right after pushing new input to the parser.
   Where immediate feedback and taking over responsibility of
   protecting against denial of service from large tokens are both
   wanted, calling "SetReparseDeferralEnabled(False)" disables reparse
   deferral for the current Expat parser instance, temporarily or
   altogether. Calling "SetReparseDeferralEnabled(True)" allows re-
   enabling reparse deferral.

   Note that "SetReparseDeferralEnabled()" has been backported to some
   prior releases of CPython as a security fix.  Check for
   availability of "SetReparseDeferralEnabled()" using "hasattr()" if
   used in code running across a variety of Python versions.

   Added in version 3.13.

xmlparser.GetReparseDeferralEnabled()

   Returns whether reparse deferral is currently enabled for the given
   Expat parser instance.

   Added in version 3.13.

"xmlparser" 객체에는 다음과 같은 어트리뷰트가 있습니다:

xmlparser.buffer_size

   "buffer_text"가 참일 때 사용되는 버퍼의 크기. 이 어트리뷰트에 새로
   운 정숫값을 대입하여 새로운 버퍼 크기를 설정할 수 있습니다. 크기가
   변경되면 버퍼가 플러시 됩니다.

xmlparser.buffer_text

   이 값을 참으로 설정하면 "xmlparser" 객체가 Expat에서 반환한 텍스트
   내용을 버퍼링하여 가능할 때마다 "CharacterDataHandler()" 콜백을 여
   러 번 호출하지 않도록 합니다. Expat은 일반적으로 모든 줄 끝에서 문
   자 데이터를 덩어리로 나누기 때문에 성능을 크게 향상할 수 있습니다.
   이 어트리뷰트는 기본적으로 거짓이며, 언제든지 변경될 수 있습니다.
   거짓일 때, 줄 넘김이 없는 데이터도 덩어리노 나뉠 수 있음에 유의하십
   시오.

xmlparser.buffer_used

   "buffer_text"가 활성화되면, 버퍼에 저장된 바이트 수. 이 바이트열은
   UTF-8로 인코딩된 텍스트를 나타냅니다. "buffer_text"가 거짓이면 이
   어트리뷰트는 의미가 없습니다.

xmlparser.ordered_attributes

   이 어트리뷰트를 0이 아닌 정수로 설정하면 어트리뷰트가 딕셔너리가 아
   닌 리스트로 보고됩니다. 어트리뷰트는 문서 텍스트에서 발견된 순서대
   로 표시됩니다. 각 어트리뷰트에 대해, 두 가지 리스트 항목이 표시됩니
   다: 어트리뷰트 이름과 어트리뷰트 값. (이 모듈의 이전 버전도 이 형식
   을 사용했습니다.) 기본적으로, 이 어트리뷰트는 거짓입니다; 언제든지
   변경될 수 있습니다.

xmlparser.specified_attributes

   0이 아닌 정수로 설정되면, 구문 분석기는 문서 인스턴스에 지정된 어트
   리뷰트만 보고하고 어트리뷰트 선언에서 파생된 어트리뷰트는 보고하지
   않습니다. 이를 설정한 응용 프로그램은 XML 프로세서의 동작에 대한 표
   준을 준수하기 위해 선언에서 사용 가능한 추가 정보를 사용할 때 특히
   주의해야 합니다. 기본적으로, 이 어트리뷰트는 거짓입니다; 언제든지
   변경될 수 있습니다.

다음 어트리뷰트는 "xmlparser" 객체가 만난 가장 최근 에러와 관련된 값을
포함하며, 일단 "Parse()"나 "ParseFile()"에 대한 호출이
"xml.parsers.expat.ExpatError" 예외를 발생시켰을 때만 올바른 값을 갖습
니다.

xmlparser.ErrorByteIndex

   에러가 발생한 바이트 인덱스.

xmlparser.ErrorCode

   문제를 지정하는 숫자 코드. 이 값은 "ErrorString()" 함수에 전달되거
   나, "errors" 객체에 정의된 상수 중 하나와 비교될 수 있습니다.

xmlparser.ErrorColumnNumber

   에러가 발생한 열 번호.

xmlparser.ErrorLineNumber

   에러가 발생한 줄 번호.

다음 어트리뷰트는 "xmlparser" 객체의 현재 구문 분석 위치와 관련된 값을
포함합니다. 구문 분석 이벤트를 보고하는 콜백 중에, 이들은 이벤트를 생
성한 첫 번째 문자 시퀀스의 위치를 나타냅니다. 콜백 외부에서 호출되면,
표시된 위치는 마지막 구문 분석 이벤트 바로 다음입니다 (관련 콜백이 있
는지에 관계없이).

xmlparser.CurrentByteIndex

   구문 분석기 입력의 현재 바이트 인덱스.

xmlparser.CurrentColumnNumber

   구문 분석기 입력의 현재 열 번호.

xmlparser.CurrentLineNumber

   구문 분석기 입력의 현재 줄 번호.

설정할 수 있는 처리기 목록은 다음과 같습니다. "xmlparser" 객체 *o*에
처리기를 설정하려면, "o.handlername = func"를 사용하십시오.
*handlername*은 다음 목록에서 취해야 하며, *func*는 올바른 수의 인자를
받아들이는 콜러블 객체여야 합니다. 달리 명시되지 않는 한, 인자는 모두
문자열입니다.

xmlparser.XmlDeclHandler(version, encoding, standalone)

   XML 선언이 구문 분석될 때 호출됩니다. XML 선언은 XML 권장 사항의 해
   당 버전에 대한 (선택적) 선언, 문서 텍스트의 인코딩 및 선택적 "독립
   형(standalone)" 선언입니다. *version*과 *encoding*은 문자열이며,
   *standalone*은 문서가 독립형으로 선언되면 "1"이 되고, 독립형이 아닌
   것으로 선언되면 "0"이 됩니다, 또는 독립형 절이 생략되면 "-1"입니다.
   Expat 버전 1.95.0 이상에서만 사용할 수 있습니다.

xmlparser.StartDoctypeDeclHandler(doctypeName, systemId, publicId, has_internal_subset)

   Expat이 문서 형 선언("<!DOCTYPE ...") 구문 분석을 시작할 때 호출됩
   니다. *doctypeName*은 제시된 대로 정확하게 제공됩니다. *systemId*와
   *publicId* 매개 변수는 지정되면 시스템(system)과 공용(public) 식별
   자를, 생략되면 "None"을 제공합니다. 문서에 내부 문서 선언 부분집합
   이 포함되어 있으면 *has_internal_subset*은 참입니다. Expat 버전 1.2
   이상이 필요합니다.

xmlparser.EndDoctypeDeclHandler()

   Expat이 문서 형 선언 구문 분석을 완료할 때 호출됩니다. Expat 버전
   1.2 이상이 필요합니다.

xmlparser.ElementDeclHandler(name, model)

   각 엘리먼트 형 선언마다 한 번씩 호출됩니다. *name*은 엘리먼트 형의
   이름이고, *model*은 콘텐츠 모델의 표현입니다.

xmlparser.AttlistDeclHandler(elname, attname, type, default, required)

   엘리먼트 형에 대해 선언된 어트리뷰트마다 호출됩니다. 어트리뷰트 리
   스트 선언이 세 개의 어트리뷰트를 선언하면 이 처리기는 어트리뷰트마
   다 한 번씩 세 번 호출됩니다. *elname*은 선언이 적용되는 엘리먼트의
   이름이고 *attname*은 선언된 어트리뷰트의 이름입니다. 어트리뷰트 형
   은 *type*으로 전달된 문자열입니다; 가능한 값은 "'CDATA'", "'ID'",
   "'IDREF'", ... 입니다. *default*는 어트리뷰트가 문서 인스턴스에 의
   해 지정되지 않을 때 사용되는 어트리뷰트의 기본값을 제공하거나, 기본
   값이 없으면 "None"입니다 ("#IMPLIED" 값). 문서 인스턴스에서 어트리
   뷰트가 필수면, *required*는 참입니다. Expat 버전 1.95.0 이상이 필요
   합니다.

xmlparser.StartElementHandler(name, attributes)

   모든 엘리먼트의 시작에서 호출됩니다. *name*은 엘리먼트 이름을 포함
   하는 문자열이고, *attributes*는 엘리먼트 어트리뷰트입니다.
   "ordered_attributes"가 참이면, 이것은 리스트입니다 (자세한 설명은
   "ordered_attributes"를 참조하십시오). 그렇지 않으면 이름을 값으로
   매핑하는 딕셔너리입니다.

xmlparser.EndElementHandler(name)

   모든 엘리먼트의 끝에서 호출됩니다.

xmlparser.ProcessingInstructionHandler(target, data)

   모든 처리 명령어(processing instruction)에서 호출됩니다.

xmlparser.CharacterDataHandler(data)

   문자 데이터에 대해 호출됩니다. 일반 문자 데이터, CDATA 표시 내용 및
   무시할 수 있는 공백에 대해 호출됩니다. 이들을 구별해야 하는 응용 프
   로그램은 "StartCdataSectionHandler", "EndCdataSectionHandler" 및
   "ElementDeclHandler" 콜백을 사용하여 필요한 정보를 수집할 수 있습니
   다. 문자 데이터는 짧더라도 덩어리로 묶일 수 있어서
   "CharacterDataHandler()"에 대한 호출을 여러 번 받을 수 있음에 유의
   하십시오. 이를 피하려면 "buffer_text" 인스턴스 어프리뷰트를 "True"
   로 설정하십시오.

xmlparser.UnparsedEntityDeclHandler(entityName, base, systemId, publicId, notationName)

   구문 분석되지 않은 (NDATA) 엔티티 선언에 대해 호출됩니다. 이것은
   Expat 라이브러리 1.2 버전에만 존재합니다; 최신 버전의 경우
   "EntityDeclHandler"를 대신 사용하십시오. (Expat 라이브러리의 하부
   함수는 더는 사용되지 않는 것으로 선언되었습니다.)

xmlparser.EntityDeclHandler(entityName, is_parameter_entity, value, base, systemId, publicId, notationName)

   모든 엔티티 선언에 대해 호출됩니다. 파라미터와 내부 엔티티의 경우,
   *value*는 엔티티의 선언된 내용을 제공하는 문자열입니다; 외부 엔티티
   의 경우 "None"이 됩니다. *notationName* 매개 변수는 구문 분석된 엔
   티티의 경우 "None"이고, 구문 분석되지 않은 엔티티의 경우는 표기법
   이름입니다. 엔티티가 파라미터 엔티티인 경우 *is_parameter_entity*는
   참이고, 일반 엔티티의 경우 거짓입니다 (대부분 응용 프로그램은 일반
   엔티티만 고려하면 됩니다). Expat 라이브러리 버전 1.95.0부터 사용 가
   능합니다.

xmlparser.NotationDeclHandler(notationName, base, systemId, publicId)

   표기법 선언에 대해 호출됩니다. *notationName*, *base*, *systemId*
   및 *publicId*는 주어지면 문자열입니다. 공용 식별자를 생략하면,
   *publicId*는 "None"이 됩니다.

xmlparser.StartNamespaceDeclHandler(prefix, uri)

   엘리먼트에 이름 공간 선언이 포함되어 있으면 호출됩니다. 이름 공간
   선언은 선언이 배치된 엘리먼트에 대한 "StartElementHandler" 가 호출
   되기 전에 처리됩니다.

xmlparser.EndNamespaceDeclHandler(prefix)

   이름 공간 선언이 포함된 엘리먼트에 대해 닫기 태그에 도달하면 호출됩
   니다. 이는 각 이름 공간 선언 스코프의 시작을 나타내기 위해
   "StartNamespaceDeclHandler" 가 호출된 순서와 반대로 엘리먼트의 각
   이름 공간 선언에 대해 한 번씩 호출됩니다. 이 처리기에 대한 호출은
   엘리먼트의 끝을 위한 해당 "EndElementHandler" 이후에 수행됩니다.

xmlparser.CommentHandler(data)

   주석에 대해 호출됩니다. *data*는 주석의 텍스트이며, 선행 "'<!-""-'"
   와 후행 "'-""->'"를 제외합니다.

xmlparser.StartCdataSectionHandler()

   CDATA 섹션의 시작에서 호출됩니다. CDATA 섹션의 구문적 시작과 종료를
   식별할 수 있으려면 이것과 "EndCdataSectionHandler" 가 필요합니다.

xmlparser.EndCdataSectionHandler()

   CDATA 섹션의 끝에서 호출됩니다.

xmlparser.DefaultHandler(data)

   적용 가능한 처리기가 지정되지 않은 XML 문서의 모든 문자에 대해 호출
   됩니다. 이것은 보고될 수 있지만, 처리기가 제공되지 않은 구성의 일부
   인 문자를 의미합니다.

xmlparser.DefaultHandlerExpand(data)

   이것은 "DefaultHandler()"와 같지만, 내부 엔티티의 확장을 막지 않습
   니다. 엔티티 참조는 기본 처리기로 전달되지 않습니다.

xmlparser.NotStandaloneHandler()

   XML 문서가 독립형 문서로 선언되지 않은 경우 호출됩니다. 외부 부분
   집합이나 파라미터 엔티티에 대한 참조가 있지만, XML 선언에서 XML 선
   언이 standalone을 "yes"로 설정하지 않은 경우에 발생합니다. 이 처리
   기가 "0"을 반환하면, 구문 분석기는 "XML_ERROR_NOT_STANDALONE" 에러
   를 발생시킵니다. 이 처리기가 설정되지 않으면, 이 조건에 대해 구문
   분석기가 예외를 발생시키지 않습니다.

xmlparser.ExternalEntityRefHandler(context, base, systemId, publicId)

   외부 엔티티에 대한 참조에 대해 호출됩니다. *base*는 "SetBase()"에
   대한 이전 호출에서 설정한 현재 베이스입니다. 공용과 시스템 식별자,
   *systemId* 및 *publicId*는 지정되면 문자열입니다; 공용 식별자가 제
   공되지 않으면 *publicId*는 "None"이 됩니다. *context* 값은 불투명하
   며 아래 설명된 대로만 사용해야 합니다.

   외부 엔티티를 구문 분석하려면, 이 처리기를 구현해야 합니다.
   "ExternalEntityParserCreate(context)"를 사용하여 서브 구문 분석기를
   만들고, 적절한 콜백으로 초기화하고, 엔티티를 구문 분석해야 합니다.
   이 처리기는 정수를 반환해야 합니다; "0"을 반환하면, 구문 분석기는
   "XML_ERROR_EXTERNAL_ENTITY_HANDLING" 에러를 발생시키고, 그렇지 않으
   면 구문 분석이 계속됩니다.

   이 처리기가 제공되지 않으면, 외부 엔티티는 제공된다면
   "DefaultHandler" 콜백에 의해 보고됩니다.


ExpatError 예외
===============

"ExpatError" 예외에는 여러 가지 흥미로운 어트리뷰트가 있습니다:

ExpatError.code

   특정 에러에 대한 Expat의 내부 에러 번호. "errors.messages" 딕셔너리
   는 이러한 에러 번호를 Expat의 에러 메시지에 매핑합니다. 예를 들면:

      from xml.parsers.expat import ParserCreate, ExpatError, errors

      p = ParserCreate()
      try:
          p.Parse(some_xml_document)
      except ExpatError as err:
          print("Error:", errors.messages[err.code])

   "errors" 모듈은 에러 메시지 상수와 이러한 메시지를 에러 코드로 역
   매핑하는 딕셔너리 "codes"도 제공합니다, 아래를 참조하십시오.

ExpatError.lineno

   에러가 감지된 줄 번호. 첫 번째 줄은 "1"로 번호가 매겨집니다.

ExpatError.offset

   에러가 발생한 줄에서의 문자 오프셋. 첫 번째 열의 번호는 "0"입니다.


예
==

다음 프로그램은 인자를 출력하기만 하는 세 개의 처리기를 정의합니다.

   import xml.parsers.expat

   # 3개의 처리기 함수
   def start_element(name, attrs):
       print('Start element:', name, attrs)
   def end_element(name):
       print('End element:', name)
   def char_data(data):
       print('Character data:', repr(data))

   p = xml.parsers.expat.ParserCreate()

   p.StartElementHandler = start_element
   p.EndElementHandler = end_element
   p.CharacterDataHandler = char_data

   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 {'id': 'top'}
   Start element: child1 {'name': 'paul'}
   Character data: 'Text goes here'
   End element: child1
   Character data: '\n'
   Start element: child2 {'name': 'fred'}
   Character data: 'More text'
   End element: child2
   Character data: '\n'
   End element: parent


콘텐츠 모델 기술
================

콘텐츠 모델은 중첩된 튜플을 사용하여 기술됩니다. 각 튜플에는 네 가지
값이 있습니다: 형, 수량 지정자(quantifier), 이름 및 자식 튜플. 자식은
단순히 추가의 콘텐츠 모델 기술입니다.

처음 두 필드의 값은 "xml.parsers.expat.model" 모듈에 정의된 상수입니다
. 이 상수는 두 그룹으로 모을 수 있습니다: 모델 형 그룹과 수량 지정자
그룹.

모델 형 그룹의 상수는 다음과 같습니다:

xml.parsers.expat.model.XML_CTYPE_ANY

   모델 이름으로 명명된 엘리먼트가 콘텐츠 모델 "ANY"를 갖도록 선언되었
   습니다.

xml.parsers.expat.model.XML_CTYPE_CHOICE

   명명된 엘리먼트가 여러 옵션 중에서 선택할 수 있도록 합니다; 이것은
   "(A | B | C)"와 같은 콘텐츠 모델에 사용됩니다.

xml.parsers.expat.model.XML_CTYPE_EMPTY

   "EMPTY"로 선언된 엘리먼트는 이 모델 형을 갖습니다.

xml.parsers.expat.model.XML_CTYPE_MIXED

xml.parsers.expat.model.XML_CTYPE_NAME

xml.parsers.expat.model.XML_CTYPE_SEQ

   일련의 모델이 차례로 나타나는 모델은 이 모델 형으로 표시됩니다.
   "(A, B, C)"와 같은 모델에 사용됩니다.

수량 지정자 그룹의 상수는 다음과 같습니다:

xml.parsers.expat.model.XML_CQUANT_NONE

   수정자가 제공되지 않아서, "A"와 같이, 정확히 한 번만 나타날 수 있습
   니다.

xml.parsers.expat.model.XML_CQUANT_OPT

   모델은 선택적입니다: "A?" 와 같이, 한 번만 나타나거나 전혀 나타나지
   않을 수 있습니다.

xml.parsers.expat.model.XML_CQUANT_PLUS

   모델은 한 번 이상 발생해야 합니다 ("A+"처럼).

xml.parsers.expat.model.XML_CQUANT_REP

   "A*"와 같이, 모델은 0번 이상 나타나야 합니다.


Expat 에러 상수
===============

"xml.parsers.expat.errors" 모듈에는 다음과 같은 상수가 제공됩니다. 이
상수는 에러가 발생했을 때 발생하는 "ExpatError" 예외 객체의 일부 어트
리뷰트를 해석하는 데 유용합니다. 이전 버전과의 호환성을 위해, 상숫값은
숫자 에러 *code*가 아니라 에러 *message*이므로, "code" 어트리뷰트를
"errors.codes[errors.XML_ERROR_*CONSTANT_NAME*]"와 비교합니다.

"errors" 모듈에는 다음과 같은 어트리뷰트가 있습니다:

xml.parsers.expat.errors.codes

   문자열 설명을 에러 코드에 매핑하는 딕셔너리.

   Added in version 3.2.

xml.parsers.expat.errors.messages

   숫자 에러 코드를 문자열 설명에 매핑하는 딕셔너리.

   Added in version 3.2.

xml.parsers.expat.errors.XML_ERROR_ASYNC_ENTITY

xml.parsers.expat.errors.XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF

   어트리뷰트 값의 엔티티 참조가 내부 엔티티 대신 외부 엔티티를 참조합
   니다.

xml.parsers.expat.errors.XML_ERROR_BAD_CHAR_REF

   문자 참조가 XML에서 잘못된 문자를 가리킵니다 (예를 들어, 문자 "0"
   또는 '"&#0;"').

xml.parsers.expat.errors.XML_ERROR_BINARY_ENTITY_REF

   엔티티 참조가 표기법으로 선언된 엔티티를 참조해서, 구문 분석할 수
   없습니다.

xml.parsers.expat.errors.XML_ERROR_DUPLICATE_ATTRIBUTE

   시작 태그에서 어트리뷰트가 두 번 이상 사용되었습니다.

xml.parsers.expat.errors.XML_ERROR_INCORRECT_ENCODING

xml.parsers.expat.errors.XML_ERROR_INVALID_TOKEN

   입력 바이트를 문자에 올바르게 대입할 수 없을 때 발생합니다; 예를 들
   어, UTF-8 입력 스트림의 NUL 바이트(값 "0").

xml.parsers.expat.errors.XML_ERROR_JUNK_AFTER_DOC_ELEMENT

   문서 엘리먼트 다음에 공백 이외의 것이 나타났습니다.

xml.parsers.expat.errors.XML_ERROR_MISPLACED_XML_PI

   입력 데이터의 시작 이외의 곳에서 XML 선언이 발견되었습니다.

xml.parsers.expat.errors.XML_ERROR_NO_ELEMENTS

   문서에 엘리먼트가 없습니다 (XML은 모든 문서에 정확히 하나의 최상위
   엘리먼트가 포함되어야 함을 요구합니다).

xml.parsers.expat.errors.XML_ERROR_NO_MEMORY

   Expat이 내부적으로 메모리를 할당하지 못했습니다.

xml.parsers.expat.errors.XML_ERROR_PARAM_ENTITY_REF

   파라미터 엔티티 참조가 허용되지 않는 위치에서 발견되었습니다.

xml.parsers.expat.errors.XML_ERROR_PARTIAL_CHAR

   입력에서 불완전한 문자가 발견되었습니다.

xml.parsers.expat.errors.XML_ERROR_RECURSIVE_ENTITY_REF

   엔티티 참조가 같은 엔티티에 대한 다른 참조를 포함합니다; 어쩌면 다
   른 이름을 통해서, 그리고 어쩌면 간접적으로.

xml.parsers.expat.errors.XML_ERROR_SYNTAX

   지정되지 않은 구문 에러를 만났습니다.

xml.parsers.expat.errors.XML_ERROR_TAG_MISMATCH

   종료 태그가 가장 안쪽에 있는 시작 태그와 일치하지 않습니다.

xml.parsers.expat.errors.XML_ERROR_UNCLOSED_TOKEN

   어떤 토큰이 (가령 시작 태그) 스트림이 끝나기 전에 닫히지 않았거나
   다음 토큰을 만났습니다.

xml.parsers.expat.errors.XML_ERROR_UNDEFINED_ENTITY

   정의되지 않은 엔티티를 참조했습니다.

xml.parsers.expat.errors.XML_ERROR_UNKNOWN_ENCODING

   문서 인코딩을 Expat에서 지원하지 않습니다.

xml.parsers.expat.errors.XML_ERROR_UNCLOSED_CDATA_SECTION

   CDATA 표시 섹션이 닫히지 않았습니다.

xml.parsers.expat.errors.XML_ERROR_EXTERNAL_ENTITY_HANDLING

xml.parsers.expat.errors.XML_ERROR_NOT_STANDALONE

   문서가 XML 선언에서 자신을 "독립형"으로 선언했지만 구문 분석기가 독
   립형이 아니라고 결정했으며 "NotStandaloneHandler" 가 설정되고 "0"을
   반환했습니다.

xml.parsers.expat.errors.XML_ERROR_UNEXPECTED_STATE

xml.parsers.expat.errors.XML_ERROR_ENTITY_DECLARED_IN_PE

xml.parsers.expat.errors.XML_ERROR_FEATURE_REQUIRES_XML_DTD

   DTD 지원이 컴파일되어 있어야 하는 작업이 요청되었지만, Expat이 DTD
   지원 없이 구성되었습니다. "xml.parsers.expat" 모듈의 표준 빌드에서
   이것이 보고되어서는 안 됩니다.

xml.parsers.expat.errors.XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING

   구문 분석이 시작된 후에 구문 분석이 시작되기 전에만 변경할 수 있는
   동작 변경이 요청되었습니다. 이것은 (현재) "UseForeignDTD()"에 의해
   서만 발생합니다.

xml.parsers.expat.errors.XML_ERROR_UNBOUND_PREFIX

   이름 공간 처리가 활성화되었을 때 선언되지 않은 접두사가 발견되었습
   니다.

xml.parsers.expat.errors.XML_ERROR_UNDECLARING_PREFIX

   문서가 접두사와 연관된 이름 공간 선언을 제거하려고 했습니다.

xml.parsers.expat.errors.XML_ERROR_INCOMPLETE_PE

   파라미터 엔티티에 불완전한 마크업이 포함되어 있습니다.

xml.parsers.expat.errors.XML_ERROR_XML_DECL

   문서에 문서 엘리먼트가 전혀 없습니다.

xml.parsers.expat.errors.XML_ERROR_TEXT_DECL

   외부 엔티티에 있는 텍스트 선언을 구문 분석하는 중 에러가 발생했습니
   다.

xml.parsers.expat.errors.XML_ERROR_PUBLICID

   허용되지 않는 문자가 공용 id에서 발견되었습니다.

xml.parsers.expat.errors.XML_ERROR_SUSPENDED

   일시 중지된 구문 분석기에 작업이 요청되었지만, 허용되지 않습니다.
   여기에는 추가 입력을 제공하거나 구문 분석기를 중지하려는 시도가 포
   함됩니다.

xml.parsers.expat.errors.XML_ERROR_NOT_SUSPENDED

   구문 분석기가 일시 중지되지 않았을 때 구문 분석기를 재개하려고 했습
   니다.

xml.parsers.expat.errors.XML_ERROR_ABORTED

   이것은 파이썬 응용 프로그램에 보고되어서는 안 됩니다.

xml.parsers.expat.errors.XML_ERROR_FINISHED

   입력을 구문 분석하는 것을 종료한 구문 분석기에 작업을 요청했지만,
   허용되지 않습니다. 여기에는 추가 입력을 제공하거나 구문 분석기를 중
   지하려는 시도가 포함됩니다.

xml.parsers.expat.errors.XML_ERROR_SUSPEND_PE

xml.parsers.expat.errors.XML_ERROR_RESERVED_PREFIX_XML

   An attempt was made to undeclare reserved namespace prefix "xml" or
   to bind it to another namespace URI.

xml.parsers.expat.errors.XML_ERROR_RESERVED_PREFIX_XMLNS

   An attempt was made to declare or undeclare reserved namespace
   prefix "xmlns".

xml.parsers.expat.errors.XML_ERROR_RESERVED_NAMESPACE_URI

   An attempt was made to bind the URI of one the reserved namespace
   prefixes "xml" and "xmlns" to another namespace prefix.

xml.parsers.expat.errors.XML_ERROR_INVALID_ARGUMENT

   이것은 파이썬 응용 프로그램에 보고되어서는 안 됩니다.

xml.parsers.expat.errors.XML_ERROR_NO_BUFFER

   이것은 파이썬 응용 프로그램에 보고되어서는 안 됩니다.

xml.parsers.expat.errors.XML_ERROR_AMPLIFICATION_LIMIT_BREACH

   The limit on input amplification factor (from DTD and entities) has
   been breached.

xml.parsers.expat.errors.XML_ERROR_NOT_STARTED

   The parser was tried to be stopped or suspended before it started.

   Added in version 3.14.

-[ 각주 ]-

[1] XML 출력에 포함된 인코딩 문자열은 적절한 표준을 준수해야 합니다.
    예를 들어, "UTF-8"은 유효하지만, "UTF8"은 유효하지 않습니다.
    https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl 과
    https://www.iana.org/assignments/character-sets/character-
    sets.xhtml 을 참조하십시오.
