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