11

PHP でカスタム DTD を使用して XML を検証する (ライブラリをインストールせずに) 方法はありますか?

4

4 に答える 4

5

PHP の DOM、特にDOMDocument::schemaValidateDOMDocument::validate を見てください。

DOMDocument::validate の例はかなり単純です:

<?php
$dom = new DOMDocument;
$dom->Load('book.xml');
if ($dom->validate()) {
    echo "This document is valid!\n";
}
?>
于 2008-09-19T13:50:23.767 に答える
3

元の質問の私の解釈は、「オンボード」DTDファイルに対して検証したい「オンボード」XMLファイルがあるということです。したがって、SorenとPayamRWDの両方のコメントで表現された「DOCTYPE要素内のローカルDTDを補間する」というアイデアを実装する方法は次のとおりです。

パブリック関数validate($ xml_realpath、$ dtd_realpath = null){
    $ xml_lines = file($ xml_realpath);
    $doc=新しいDOMDocument;
    if($ dtd_realpath){
        // DOCTYPE行内にDTDを挿入します:
        $ dtd_lines = file($ dtd_realpath);
        $ new_lines = array();
        foreach($ xml_lines as $ x){
            // DOCTYPE SYSTEM "blah blah"形式を想定します:
            if(preg_match('/ DOCTYPE /'、$ x)){
                $ y = preg_replace('/ SYSTEM "(。*)" /'、 "[\ n" .implode( "\ n"、$ dtd_lines)。 "\ n]"、$ x);
                $ new_lines [] = $ y;
            } そうしないと {
                $ new_lines [] = $ x;
            }
        }
        $ doc-> loadXML(implode( "\ n"、$ new_lines));
    } そうしないと {
        $ doc-> loadXML(implode( "\ n"、$ xml_lines));
    }
    //ユーザーエラー処理を有効にします
    libxml_use_internal_errors(true);
    if(@ $ doc-> validate()){
        echo "有効です!\ n";
    } そうしないと {
        echo "無効:\ n";
        $ errors = libxml_get_errors();
        foreach($ errors as $ error){
            print_r($ error、true);
        }
    }
}

簡潔にするためにエラー処理は抑制されていることに注意してください。補間を処理するためのより良い/より一般的な方法があるかもしれません。しかし、私実際にこのコードを実際のデータで使用しており、PHPバージョン5.2.17で動作します。

于 2011-09-12T14:15:15.847 に答える
3

文字列に 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";
}
于 2011-06-30T09:48:18.943 に答える
1

「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>
于 2011-03-03T16:11:08.457 に答える