Я пытаюсь проверить этот документ в PHP с помощью schemaValidate DOMdocument:
<?xml version="1.0" encoding="UTF-8"?> <works xmlns="http://pbn.nauka.gov.pl/-/ns/bibliography" pbn-unit-id="1388"><article><title>Mukowiscydoza</title></article></works>
используя $ domDocument-> schemaValidate (‘pbn-report.xsd’)
Ссылка на XSD:
https://pbn.nauka.gov.pl/help/images/files/pbn-report.xsd.zip
… и я всегда получаю ошибку
Ошибка 1871: Элемент ‘article’: этот элемент не ожидается. ожидаемый
один из ( {http://pbn.nauka.gov.pl/-/ns/bibliography}статья,
{http://pbn.nauka.gov.pl/-/ns/bibliography}книга,
{http://pbn.nauka.gov.pl/-/ns/bibliography} глава). на линии 0
Для меня это непонятно. Почему я получаю сообщение об ошибке при указании пространства имен по умолчанию?
Решаемые.
Оказывается, когда вы создаете DOMDocument, когда вы добавляете элемент каждый раз, когда вам нужно дать пространство имен. При создании документа (saveXML) не будет никакой разницы, но если вы запустите schemaValidate, валидатор проверяет объект DOMDocument, а не сгенерированный XML.
Другими словами, этот код:
$domDocument = new DOMDocument('1.0', "UTF-8");
$domWorks = $domDocument->createElementNS("http://pbn.nauka.gov.pl/-/ns/bibliography",'works');
$domWorksId = $domDocument->createAttribute('pbn-unit-id');
$domWorksId->value = PBNID;
$domWorks->appendChild($domWorksId);
$domDocument->appendChild($domWorks);
$domArticle = $domDocument->createElement('article');
$domArticle->appendChild($domDocument->createElement('title','Mukowiscydoza'));
$domWorks->appendChild($domArticle);
echo htmlentities($domDocument->saveXML());
генерирует тот же XML, что и этот код
$domDocument = new DOMDocument('1.0', "UTF-8");
$domWorks = $domDocument->createElementNS("http://pbn.nauka.gov.pl/-/ns/bibliography",'works');
$domWorksId = $domDocument->createAttribute('pbn-unit-id');
$domWorksId->value = PBNID;
$domWorks->appendChild($domWorksId);
$domDocument->appendChild($domWorks);
$domArticle = $domDocument->createElementNS("http://pbn.nauka.gov.pl/-/ns/bibliography",'article');
$domArticle->appendChild($domDocument->createElementNS("http://pbn.nauka.gov.pl/-/ns/bibliography",'title','Mukowiscydoza'));
$domWorks->appendChild($domArticle);
echo htmlentities($domDocument->saveXML());
Но если вы проверите схему
$domDocument->schemaValidate('pbn-report.xsd');
, первый код вернет ошибку.
Странный …
Странный …
Ну не совсем. Пока документ находится в памяти, информация о пространстве (ах) имен с элементами сохраняется.
В этом случае два разных метода / параметра здесь действительно иметь значение, даже если вы не видите различий в сгенерированном XML (впоследствии):
// null namespace
$domArticle = $domDocument->createElement('article');
// vs. concrete namespace
$domArticle = $domDocument->createElementNS(
'http://pbn.nauka.gov.pl/-/ns/bibliography', 'article'
);
Затем вы сериализуете документ (то, что вы описываете как «генерирует тот же XML») как XML, и затем вы загружаете этот XML обратно в память. Тогда элементы без пространства имен больше не будут находиться в пустом пространстве имен, потому что они наследуют свое пространство имен от родительского элемента.
Поэтому вы должны различать документ и его элементы в памяти (DOM) и в сериализованной форме (строка, файл).
Вы можете получить аналогичные эффекты при выполнении XSLT-преобразований. Поэтому, если вы испытываете что-то странное, стоит учесть, что документ в памяти не отражает того, о чем вы думаете, даже если он создает похожий — или даже точно такой же — выглядящий XML;)
Попробуйте поместить xmlns в элемент article, затем повторите попытку.
xmlns="http://pbn.nauka.gov.pl/-/ns/bibliography"