문제

PHP에서 사용자 정의 DTD를 사용하여 XML의 유효성을 검사하는 방법(라이브러리를 설치하지 않고)이 있습니까?

도움이 되었습니까?

해결책

보세요 PHP의 DOM, 특히 DOMDocument::schemaValidate 그리고 DOMDocument::검증.

DOMDocument::validate의 예는 매우 간단합니다.

<?php
$dom = new DOMDocument;
$dom->Load('book.xml');
if ($dom->validate()) {
    echo "This document is valid!\n";
}
?>

다른 팁

문자열에 dtd가 있는 경우 다음을 사용하여 이에 대해 유효성을 검사할 수 있습니다. 데이터 래퍼 dtd의 경우:

$xml = '<?xml version="1.0"?>
        <!DOCTYPE note SYSTEM "note.dtd">
        <note>
            <to>Tove</to>
            <from>Jani</from>
            <heading>Reminder</heading>
            <body>Don\'t forget me this weekend!</body>
        </note>';

$dtd = '<!ELEMENT note (to,from,heading,body)>
        <!ELEMENT to (#PCDATA)>
        <!ELEMENT from (#PCDATA)>
        <!ELEMENT heading (#PCDATA)>
        <!ELEMENT body (#PCDATA)>';


$root = 'note';

$systemId = 'data://text/plain;base64,'.base64_encode($dtd);

$old = new DOMDocument;
$old->loadXML($xml);

$creator = new DOMImplementation;
$doctype = $creator->createDocumentType($root, null, $systemId);
$new = $creator->createDocument(null, null, $doctype);
$new->encoding = "utf-8";

$oldNode = $old->getElementsByTagName($root)->item(0);
$newNode = $new->importNode($oldNode, true);
$new->appendChild($newNode);

if (@$new->validate()) {
    echo "Valid";
} else {
    echo "Not valid";
}

원래 질문에 대한 나의 해석은 "온보드" DTD 파일에 대해 유효성을 검사하려는 "온보드" XML 파일이 있다는 것입니다.Soren과 PayamRWD의 의견에서 표현된 "DOCTYPE 요소 내부에 로컬 DTD 삽입" 아이디어를 구현하는 방법은 다음과 같습니다.

public function validate($xml_realpath, $dtd_realpath=null) {
    $xml_lines = file($xml_realpath);
    $doc = new DOMDocument;
    if ($dtd_realpath) {
        // Inject DTD inside DOCTYPE line:
        $dtd_lines = file($dtd_realpath);
        $new_lines = array();
        foreach ($xml_lines as $x) {
            // Assume DOCTYPE SYSTEM "blah blah" format:
            if (preg_match('/DOCTYPE/', $x)) {
                $y = preg_replace('/SYSTEM "(.*)"/', " [\n" . implode("\n", $dtd_lines) . "\n]", $x);
                $new_lines[] = $y;
            } else {
                $new_lines[] = $x;
            }
        }
        $doc->loadXML(implode("\n", $new_lines));
    } else {
        $doc->loadXML(implode("\n", $xml_lines));
    }
    // Enable user error handling
    libxml_use_internal_errors(true);
    if (@$doc->validate()) {
        echo "Valid!\n";
    } else {
        echo "Not valid:\n";
        $errors = libxml_get_errors();
        foreach ($errors as $error) {
            print_r($error, true);
        }
    }
}

간결성을 위해 오류 처리가 억제되었으며 보간을 처리하는 더 나은/더 일반적인 방법이 있을 수 있습니다.하지만 나는 가지다 실제로 이 코드를 실제 데이터와 함께 사용했으며 PHP 버전 5.2.17에서 작동합니다.

"owenmarshall" 답변을 완성하려고 합니다.

xml-validator.php에서:

html, 헤더, 본문 등을 추가하세요.

<?php

$dom = new DOMDocument; <br/>
$dom->Load('template-format.xml');<br/>
if ($dom->validate()) { <br/>
    echo "This document is valid!\n"; <br/>
}

?>

템플릿 형식.xml:

<?xml version="1.0" encoding="utf-8"?>

<!-- DTD to Validate against (format example) -->

<!DOCTYPE template-format [  <br/>
  <!ELEMENT template-format (template)>  <br/>
  <!ELEMENT template (background-color, color, font-size, header-image)>  <br/>
  <!ELEMENT background-color   (#PCDATA)>  <br/>
  <!ELEMENT color (#PCDATA)>  <br/>
  <!ELEMENT font-size (#PCDATA)>  <br/>
  <!ELEMENT header-image (#PCDATA)>  <br/>
]>

<!-- XML example -->

<template-format>

<template>

<background-color>&lt;/background-color>  <br/>
<color>&lt;/color>  <br/>
<font-size>&lt;/font-size>  <br/>
<header-image>&lt;/header-image>  <br/>

</template> 

</template-format>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top