Ошибка simplexml_load_string при использовании строкового параметра в стиле heredoc

Я пытаюсь один простой пример PHP XML следующим образом.

// code of PHP
===================================================
<?php
  $string = <<<XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
XML;

  print "BEGIN</br>"; 
  print "String:</br>{$string}";

  $xml = simplexml_load_string($string);
  print "</br>XML Obj:</br>";
  print_r($xml);
  print "</br>Var Dump:</br>";  
  var_dump($xml);
  print "</br>END"; 
?>
===================================================

и выходы, кажется, в порядке

// output
===================================================
BEGIN
String:
George John Reminder Don't forget the meeting!
XML Obj:
SimpleXMLElement Object ( [to] => George [from] => John [heading] => Reminder [body] => Don't forget the meeting! )
Var Dump:
object(SimpleXMLElement)#1 (4) { ["to"]=> string(6) "George" ["from"]=> string(4) "John" ["heading"]=> string(8) "Reminder" ["body"]=> string(25) "Don't forget the meeting!" }
END
===================================================

Хотя, когда я пытаюсь отформатировать первую строку строки в стиле heredoc, добавив несколько пробелов перед ней, добавив два пробела перед следующей строкой <?xml version="1.0" encoding="ISO-8859-1"?>, Тогда он всегда не мог выводить информацию об объекте $xml.

// code of PHP
===================================================
<?php
  $string = <<<XML
  <?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
XML;
... ...
===================================================

// output
===================================================
BEGIN
String:
George John Reminder Don't forget the meeting!
XML Obj:

Var Dump:
bool(false)
END

Надеюсь, кто-нибудь может мне помочь!!! Спасибо большое.

1 ответ

Решение

Это не допустимый XML. Посмотрите на спецификации XML для документов:

document    ::=     prolog element Misc*
prolog      ::=     XMLDecl? Misc* (doctypedecl Misc*)?
XMLDecl     ::=     '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'

document описывает, из каких других XML-маркеров создаются XML-токены, начиная с prolog, Это может содержать XMLDecl, который снова начинается с <?xml, Вкратце: пробелы не допускаются до объявления, если они есть.


Если вы находитесь под контролем XML (который вам кажется): просто не делайте этого, я бы посчитал это злонамеренным, так как каждый должен иметь дело с кодом после того, как вы задаетесь вопросом, что происходит.

Если вы не можете изменить ввод, потому что кто-то еще отправляет испорченные файлы XML:

  • скажите ему, чтобы отправить правильно сформированный XML или
  • "препроцессировать" не-XML с trim($string) как уже предложено в комментариях.
Другие вопросы по тегам