PHP의 내장 XML 파서 (국외 라이브러리 기반)는 복잡한 XML 데이터를 다룰 때 매우 강력한 도구입니다. XML_PARSER_CREATE () 와 함께 제공되는 처리 기능을 통해 XML 구조를 유연하게 구문 분석 할 수 있습니다. 특히 깊은 중첩 레벨과 많은 요소로 XML 문서에 직면 할 때 사용자 정의 요소 핸들러는 구문 분석 효율과 가독성을 크게 향상시킵니다.
이 기사에서는 XML_SET_ELENMER_HANDLER ()를 사용하여 XML 요소 프로세서를 사용자 정의하고 샘플 코드로 복잡한 XML 데이터 구조를 구문 분석하는 방법에 대해 자세히 설명합니다.
XML_PARSE ()를 사용하여 XML 스트림을 구문 분석 할 때 xml_set_element_handler ()를 통해 파서에 대한 두 개의 콜백 함수를 등록 할 수 있습니다.
startelementhandler : 태그를 시작하는 콜백 함수
EndElementHandler : 엔딩 태그에 대한 콜백 함수
이 두 기능의 서명은 일반적으로 다음과 같습니다.
function startElement($parser, $name, $attrs)
function endElement($parser, $name)
여기서 $ 이름 은 현재 노드의 이름이고 $ attrs는 노드의 속성을 나타내는 연관 배열입니다.
API에서 다음 형식으로 XML 데이터를 얻는다 고 가정 해보십시오.
<catalog>
<book id="001">
<title>PHP 개발 실습</title>
<author>장 산</author>
<price currency="CNY">89.00</price>
</book>
<book id="002">
<title>심층적 인 이해 XML</title>
<author>Li Si</author>
<price currency="CNY">75.50</price>
</book>
</catalog>
우리는 각 책의 제목, 저자 및 가격 정보를 추출하고 출력하는 파서를 작성합니다.
<?php
$xmlData = file_get_contents('https://m66.net/api/books.xml');
// 구문 분석 결과를 저장하는 데 사용됩니다
$books = [];
$currentBook = [];
$currentTag = "";
// 만들다 XML 파서
$parser = xml_parser_create("UTF-8");
// 시작 및 엔드 태그의 처리 기능 설정
xml_set_element_handler($parser, "startElement", "endElement");
// 문자 데이터 처리 기능을 설정합니다
xml_set_character_data_handler($parser, "characterData");
// 设置파서参数
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false); // 레이블 케이스를 일관성있게 유지하십시오
// 처리 기능을 정의하십시오
function startElement($parser, $name, $attrs) {
global $currentBook, $currentTag;
$currentTag = $name;
if ($name == "book") {
$currentBook = [
"id" => $attrs['id'] ?? null,
"title" => "",
"author" => "",
"price" => "",
"currency" => ""
];
}
if ($name == "price" && isset($attrs['currency'])) {
$currentBook['currency'] = $attrs['currency'];
}
}
function endElement($parser, $name) {
global $books, $currentBook, $currentTag;
if ($name == "book") {
$books[] = $currentBook;
$currentBook = [];
}
$currentTag = "";
}
function characterData($parser, $data) {
global $currentBook, $currentTag;
$data = trim($data);
if (empty($data)) return;
switch ($currentTag) {
case "title":
$currentBook["title"] .= $data;
break;
case "author":
$currentBook["author"] .= $data;
break;
case "price":
$currentBook["price"] .= $data;
break;
}
}
// 구문 분석을 실행하십시오
if (!xml_parse($parser, $xmlData, true)) {
die(sprintf("XML 실수: %s 에서 %d 좋아요",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
}
xml_parser_free($parser);
// 출력 분석 결과
foreach ($books as $book) {
echo "책 제목: {$book['title']}\n";
echo "작가: {$book['author']}\n";
echo "가격: {$book['price']} {$book['currency']}\n";
echo "------------------------\n";
}
상태 변수를 사용하여 컨텍스트 추적 <br> $ currentTag 및 $ currentBook 과 같은 상태 변수는 깊게 중첩 될 때 매우 중요하며 현재 어떤 노드를 결정하는 데 도움이 될 수 있습니다.
공백 문자 필터
캐릭터 데이터는 많은 수의 최신 라인과 공간을받을 수 있으며 비어 있는지 확인하기 위해 ()을 다듬어야 합니다.
반복되는 과제를 피하십시오 <br> 일부 태그 내용은 여러 세그먼트 (특히 긴 텍스트)로 반환 될 수 있으며 . = 스 플라이 싱은 데이터 잘림을 방지 할 수 있습니다.
네임 스페이스를 사용하여 복잡한 XML을 처리합니다
XML이 네임 스페이스를 사용하는 경우 xml_set_start_namespace_decl_handler () 와 같은 고급 API를 사용하여 구문 분석과 협력하는 것이 좋습니다.
관련 태그:
xml_parse