1

OSX で PHP 5.3.15 を使用して .xsd スキーマ ファイルに対してスクリプトから生成した XML を検証しようとしていますが、定義DOMDocument::schemaValidate()の検証に失敗します。typeに変更しようとしましたxsi:typeが、それでも失敗します。私の XML は、問題なく検証される XML ファイルと同じように見えます。私はここで何が起こっているのか途方に暮れています....

検証に失敗した XML は次のとおりです。

<DataGroups>
    <DataGroup xsi:type="ReportDataGroup"/>

    <DataGroup xsi:type="AlertDataGroup">
      // some XML here
    </DataGroup>

    <DataGroup xsi:type="MetricGroupingDataGroup">
      // some XML here
    </DataGroup>
</DataGroups>

それぞれについて、次の警告のいずれかが表示されますDataGroup

Severity: Warning
Message:  DOMDocument::schemaValidate(): Element 'DataGroup': The type definition is abstract.

または、より具体的に

Error 1876: Element 'DataGroup': The type definition is abstract

エラーを調べました。それは:

XML_SCHEMAV_CVC_TYPE_2 = 1876 : 1876

.xsd ファイルの関連部分は次のとおりです。

<xs:complexType name="DataGroupType" abstract="true"/>

<xs:complexType name="AlertDataGroup">
    <xs:complexContent>
        <xs:extension base="DataGroupType">
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element name="AlertBase" type="BaseAlertType"/>
            </xs:choice>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>
<xs:complexType name="ReportDataGroup">
    <xs:complexContent>
        <xs:extension base="DataGroupType">
            <xs:sequence minOccurs="0" maxOccurs="unbounded">
                <xs:element name="SmartReportTemplate" type="SmartReportTemplateType"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>
<xs:complexType name="MetricGroupingDataGroup">
    <xs:complexContent>
        <xs:extension base="DataGroupType">
            <xs:sequence minOccurs="0" maxOccurs="unbounded">
                <xs:element name="MetricGrouping" type="MetricGroupingType"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

ここで何が起こっているのでしょうか?トラブルシューティングに一日中費やしましたが、役に立ちませんでした。検証する必要があります。そうしないと、ロード時に検証されるため、反対側のアプリケーションはファイルを読み取れません。

アップデート:

生成された XML と、正常に検証される事前に存在するファイルを並べて diff を実行しました。違いはまったく見られません。また、特定のスキーマに対して検証できる XML 検証サービスとツールもいくつか見つけました。誰もがエラーなしで完全に検証しました。そのため、ローカル検証がまだ失敗する理由がわかりません。

私は正しい名前空間を設定しています:

$xml->documentElement->setAttributeNS('http://www.w3.org/2000/xmlns/' ,'xmlns:introscope', 'generated://introscope.xsd');
$xml->documentElement->setAttributeNS('http://www.w3.org/2000/xmlns/' ,'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$xml->documentElement->setAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'noNamespaceSchemaLocation', 'http://example.com/path/to/schema.xsd');

そして、私のルートノードは、すべての名前空間が正しく設定された、検証されたファイルのものと同一であるように見えます:

<ManagementModule xmlns:introscope="generated://introscope.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="1.0" Editable="true" DescriptionContentType="text/plain" IsActive="true" Name="ManagementModuleName" xsi:noNamespaceSchemaLocation="http://example.com/path/to/schema.xsd">

更新#2:

おっと... この問題の 2 日後、ストリームを検証しようとしたときにのみ失敗することに気付きました。XML をファイルに保存して検証しようとすると、問題なく動作します。何?

更新 #3:

要求に応じてコード スニペットを追加します。

ここに検証コードがあります。このスニペットはインターネット上に浮かんでおり、複数の人が正常に使用しています。

    function libxml_display_error($error)
    {
        $return = "\n";
        switch ($error->level) {
            case LIBXML_ERR_WARNING:
                $return .= "Warning $error->code: ";
                break;
            case LIBXML_ERR_ERROR:
                $return .= "Error $error->code: ";
                break;
            case LIBXML_ERR_FATAL:
                $return .= "<b>Fatal Error $error->code: ";
                break;
        }
        $return .= trim($error->message);
        if ($error->file) {
            $return .=    " in $error->file";
        }
        $return .= " on line $error->line\n";

        return $return;
    }

    function libxml_display_errors() {
        $errors = libxml_get_errors();
        foreach ($errors as $error) {
            print libxml_display_error($error);
        }
        libxml_clear_errors();
    }

検証コードはこちら。明らかに、xml が構築された後に実行しますが、わかりやすくするためにここに置きます。

libxml_use_internal_errors(true);

if (!$xml->schemaValidate('/local/path/to/schema.xsd')) {
    print '<b>DOMDocument::schemaValidate() Generated Errors!</b>';
    libxml_display_errors();

} else {
    echo "VALID XML";
}

このように XML を作成すると、検証されません。

$xml = new DOMDocument();
$xml = Array2XML::createXML('ManagementModule', $json);

$xml->documentElement->setAttributeNS('http://www.w3.org/2000/xmlns/' ,'xmlns:introscope', 'generated://introscope.xsd');
$xml->documentElement->setAttributeNS('http://www.w3.org/2000/xmlns/' ,'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$xml->documentElement->setAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'noNamespaceSchemaLocation', 'http://example.com/path/to/schema.xsd');

そして、次のエラーが表示されます。

Error 1876: Element 'DataGroup': The type definition is abstract. on line 0
Error 1876: Element 'DataGroup': The type definition is abstract. on line 0
Error 1876: Element 'DataGroup': The type definition is abstract. on line 0

上記のコードに次の行を追加すると、出力を次のファイルに保存しますtext.xml

echo $xml->saveXML();

次に、次の操作を行います。

$xml = new DOMDocument();
$xml->load('/path/to/test.xml');

そして、検証しようとすると、私は得る

VALID XML
4

0 に答える 0