PHP DOMDocument: как включить строку XML?

0

Я создаю xml файл и должен включать сегмент xml, сохраненный в базе данных (да, я бы хотел, чтобы это было не так).

    // parent element
    $parent = $dom->createElement('RecipeIngredients');

    // the xml string I want to include
    $xmlStr = $row['ingredientSectionXml'];

    // load xml string into domDocument
    $dom->loadXML( $xmlStr );

    // add all Ingredient Sections from xmlStr as children of $parent
    $xmlList = $dom->getElementsByTagName( 'IngredientSection' );
    for ($i = $xmlList->length; --$i >= 0; ) {
      $elem = $xmlList->item($i);
      $parent->appendChild( $elem );
    }

    // add the parent to the $dom doc
    $dom->appendChild( $parent );

Прямо сейчас, я получаю следующую ошибку, когда я ударяю по строке $parent->appendChild( $elem );

Fatal error: Uncaught exception 'DOMException' with message 'Wrong Document Error'

XML в строке может выглядеть примерно так: Важным моментом является то, что может быть несколько IngredientSections, все из которых необходимо добавить к элементу $ parent.

<IngredientSection name="Herbed Cheese">
  <RecipeIngredient>
    <Quantity>2</Quantity>
    <Unit>cups</Unit>
    <Item>yogurt cheese</Item>
    <Note>(see Tip)</Note>
    <MeasureType/>
    <IngredientBrand/>
  </RecipeIngredient>
  <RecipeIngredient>
    <Quantity>2</Quantity>
    <Unit/>
    <Item>scallions</Item>
    <Note>, trimmed and minced</Note>
    <MeasureType/>
    <IngredientBrand/>
  </RecipeIngredient>
<IngredientSection name="Cracked-Wheat Crackers">
</IngredientSection>
  <RecipeIngredient>
    <Quantity>2</Quantity>
    <Unit>teaspoon</Unit>
    <Item>salt</Item>
    <Note/>
    <MeasureType/>
    <IngredientBrand/>
  </RecipeIngredient>
  <RecipeIngredient>
    <Quantity>1 1/4</Quantity>
    <Unit>cups</Unit>
    <Item>cracked wheat</Item>
    <Note/>
    <MeasureType/>
    <IngredientBrand/>
  </RecipeIngredient>
</IngredientSection>
Теги:
domdocument

2 ответа

2
Лучший ответ

Вот два возможных решения:

Импорт из исходного документа

Это работает только в том случае, если строка XML является допустимым документом. Вам нужно импортировать элемент документа или его потомка. Зависит от той части, которую вы хотите добавить в целевой документ.

$xml = "<child>text</child>";

$source = new DOMDocument();
$source->loadXml($xml);

$target = new DOMDocument();
$root = $target->appendChild($target->createElement('root'));
$root->appendChild($target->importNode($source->documentElement, TRUE));

echo $target->saveXml();

Вывод:

<?xml version="1.0"?>
<root><child>text</child></root>

Использовать фрагмент документа

Это работает для любого действительного фрагмента XML. Даже если у него нет корневого узла.

$xml = "text<child>text</child>";

$target = new DOMDocument();
$root = $target->appendChild($target->createElement('root'));

$fragment = $target->createDocumentFragment();
$fragment->appendXml($xml);
$root->appendChild($fragment);

echo $target->saveXml();

Вывод:

<?xml version="1.0"?>
<root>text<child>text</child></root>
  • 0
    Спасибо! Я закончил тем, что создал второй DomDocument (ваш первый пример). Оглядываясь назад, можно сказать, что при использовании фрагмента документа было бы меньше накладных расходов.
0

Вам нужно использовать ->importNode() вместо ->appendChild(). Ваши фрагменты XML исходят из совершенно другого документа XML, и appendChild будет принимать только узлы, которые являются частью SAME XML. importNode() будет принимать "чужие" узлы и включать их в основное дерево.

  • 0
    importNode() не является методом на DOMElement . И я получаю ту же «Ошибку неправильного документа», когда я пытаюсь $parent->appendChild( $dom->importNode( $elem, true ) ); , Можете ли вы привести пример?
  • 0
    Интересно. Мой код работает после следующего ответа на этот пост . Кажется, мне пришлось загрузить строку xml во второй отдельный DOMDocument и импортировать этот элемент. Похоже, на создание второго DOMDocument уходит много времени - я подозреваю, что для этого и нужен DOMDocumentFragment , но мне нужно найти пример.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню