我正在尝试使用在 OSX 上使用 PHP 5.3.15 验证从脚本生成的 XML 与 .xsd 模式文件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 和预退出文件进行了并排比较,验证得很好。根本看不出有什么区别。我还发现了一些能够针对给定模式进行验证的 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