web-dev-qa-db-ja.com

文字列がPHPで警告を表示せずに有効なXMLであるかどうかを確認する方法

私はこの simplexml_load_string()を使用してxmlとして文字列の妥当性をチェックしようとしていましたドキュメント 関数ですが、多くの警告メッセージが表示されます。

エラーを抑制せずに文字列が有効なXMLかどうかを確認するにはどうすればよいですか( @の先頭 )エラーおよび

46
jspeshu

Libxml_use_internal_errors()を使用してすべてのXMLエラーを抑制し、libxml_get_errors()を使用してそれらを繰り返し処理します。

単純なXML読み込み文字列

libxml_use_internal_errors(true);

$doc = simplexml_load_string($xmlstr);
$xml = explode("\n", $xmlstr);

if (!$doc) {
    $errors = libxml_get_errors();

    foreach ($errors as $error) {
        echo display_xml_error($error, $xml);
    }

    libxml_clear_errors();
}
72
Tjirp

ドキュメント から:

ドキュメントをロードする際のXMLエラーの処理は非常に簡単なタスクです。 libxml機能を使用すると、ドキュメントの読み込み時にすべてのXMLエラーを抑制し、エラーを反復処理できます。

libxml_get_errors()によって返されるlibXMLErrorオブジェクトには、エラーのmessagelineおよびcolumn(位置)を含むいくつかのプロパティが含まれます。 。

libxml_use_internal_errors(true);
$sxe = simplexml_load_string("<?xml version='1.0'><broken><xml></broken>");
if (!$sxe) {
    echo "Failed loading XML\n";
    foreach(libxml_get_errors() as $error) {
        echo "\t", $error->message;
    }
}

参照: - libxml_use_internal_errors

19
Felix Kling

このような私のバージョン:

//validate only XML. HTML will be ignored.

function isValidXml($content)
{
    $content = trim($content);
    if (empty($content)) {
        return false;
    }
    //html go to hell!
    if (stripos($content, '<!DOCTYPE html>') !== false) {
        return false;
    }

    libxml_use_internal_errors(true);
    simplexml_load_string($content);
    $errors = libxml_get_errors();          
    libxml_clear_errors();  

    return empty($errors);
}

テスト:

//false
var_dump(isValidXml('<!DOCTYPE html><html><body></body></html>'));
//true
var_dump(isValidXml('<?xml version="1.0" standalone="yes"?><root></root>'));
//false
var_dump(isValidXml(null));
//false
var_dump(isValidXml(1));
//false
var_dump(isValidXml(false));
//false
var_dump(isValidXml('asdasds'));
10
admin

これを試して

//check if xml is valid document
public function _isValidXML($xml) {
    $doc = @simplexml_load_string($xml);
    if ($doc) {
        return true; //this is valid
    } else {
        return false; //this is not valid
    }
}
9
Jkhaled

ここで私が少し前に書いたクラスの小片:

/**
 * Class XmlParser
 * @author Francesco Casula <[email protected]>
 */
class XmlParser
{
    /**
     * @param string $xmlFilename Path to the XML file
     * @param string $version 1.0
     * @param string $encoding utf-8
     * @return bool
     */
    public function isXMLFileValid($xmlFilename, $version = '1.0', $encoding = 'utf-8')
    {
        $xmlContent = file_get_contents($xmlFilename);
        return $this->isXMLContentValid($xmlContent, $version, $encoding);
    }

    /**
     * @param string $xmlContent A well-formed XML string
     * @param string $version 1.0
     * @param string $encoding utf-8
     * @return bool
     */
    public function isXMLContentValid($xmlContent, $version = '1.0', $encoding = 'utf-8')
    {
        if (trim($xmlContent) == '') {
            return false;
        }

        libxml_use_internal_errors(true);

        $doc = new DOMDocument($version, $encoding);
        $doc->loadXML($xmlContent);

        $errors = libxml_get_errors();
        libxml_clear_errors();

        return empty($errors);
    }
}

テスト目的では、ストリームおよび vfsStream でも問題なく動作します。

3

場合

Google Merchant XMLフィードの可用性を時々確認してください。

フィードにはDTDがないため、 validate() は機能しません。

溶液

_// disable forwarding those load() errors to PHP
libxml_use_internal_errors(true);
// initiate the DOMDocument and attempt to load the XML file
$dom = new \DOMDocument;
$dom->load($path_to_xml_file);
// check if the file contents are what we're expecting them to be
// `item` here is for Google Merchant, replace with what you expect
$success = $dom->getElementsByTagName('item')->length > 0;
// alternatively, just check if the file was loaded successfully
$success = null !== $dom->actualEncoding;
_

length 上記には、ファイルに実際にリストされている製品の数が含まれています。代わりにタグ名を使用できます。

論理

他のタグ名で getElementsByTagName() を呼び出すことができます(使用したitemはGoogle Merchant用です。ケースは異なる場合があります)、または 他のプロパティ _$dom_オブジェクト自体。ロジックは同じままです。ファイルの読み込み時にエラーが発生したかどうかを確認する代わりに、実際に操作(または実際に必要な値が含まれているかどうかを具体的に確認)する方が信頼性が高いと思います。

最も重要: validate() とは異なり、これにはXMLにDTDが必要ありません。

1
aexl