我正在尝试验证我使用DOMDocument::schemaValidate()
在OSX上使用PHP 5.3.15对我的脚本生成的.xsd模式文件生成的XML,但它无法验证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和预先退出文件进行了并排差异验证。根本看不出任何差异。我还发现了一些能够针对给定模式进行验证的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