1

我正在尝试使用在 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
4

0 回答 0