Мне нужно настроить теги XML - PullRequest
0 голосов
/ 01 октября 2019

Мне нужно внести некоторые изменения в теги xml, которые я использую. Мне нужно собрать некоторые из этих тегов в другие теги. Например:

<image> image_url </image>
the tags
<Images>
    <Image> image_url <image>
</Images>

должно быть

Мне также может понадобиться использовать некоторые теги ниже или выше существующего тега

ДляПример:

<productname> pr_name </productname>
<newproductname> pr_name </newproductname>

Проверка вывода XML:

<Root>
  <Products>
    <Product>
        <productname> pr_name </productname>
        <price> pr_price </price>
        <sku> pr_sku </sku>
        <Image> image_url <image>
    <Product>
  </Products>
</Root>

Я хочу это следующим образом:)

<Root>
  <Products>
    <Product>
        <newproductname> pr_name </newproductname>

        <productname> pr_name </productname>
        <price> pr_price </price>
        <sku> pr_sku </sku>
        <Images>
            <Image> image_url <image>
        </Images>

        <newsku> pr_newsku </newsku>
    <Product>
  </Products>
</Root>

Как внести изменения в эту структуру , которую я использую как.

header('Content-Type: application/xml');
$xml = new DOMDocument();
$xml->preserveWhiteSpace = false;
$xml->formatOutput = true;
$xml->load('test.xml');
$xml_string = $xml->saveXML();
echo $xml_string;

1 Ответ

0 голосов
/ 01 октября 2019

Учитывая приведенный ниже пример XML, который основан на цитируемом в вопросе, но немного расширен и исправил неправильно сформированный XML, как показано выше, вы можете легко получить желаемую структуру с осторожным использованием DOMXPath и insertBefore -с небольшим поворотом на последнем, чтобы фактически выполнить insertAfter

<code>$xml='<?xml version="1.0" encoding="UTF-8"?>
        <Root>
            <Products>
                <Product>
                    <productname> pr_name 1</productname>
                    <price> pr_price 1</price>
                    <sku> pr_sku 1</sku>
                    <Image> image_url 1.1</Image>
                    <Image> image_url 1.2</Image>
                </Product>
                <Product>
                    <productname> pr_name 2</productname>
                    <price> pr_price 2</price>
                    <sku> pr_sku 2</sku>
                    <Image> image_url 2</Image>
                </Product>

                <Product>
                    <productname> pr_name 3</productname>
                    <price> pr_price 3</price>
                    <sku> pr_sku 3</sku>
                    <Image> image_url 3.1</Image>
                    <Image> image_url 3.2</Image>
                    <Image> image_url 3.3</Image>
                </Product>

                <Product>
                    <productname> pr_name 4</productname>
                    <price> pr_price 4</price>
                    <sku> pr_sku 4</sku>
                </Product>
            </Products>
        </Root>';



$dom=new DOMDocument('1.0','utf-8');
$dom->formatOutput=true;
$dom->validateOnParse=false;
$dom->recover=true;
$dom->strictErrorChecking=false;
$dom->preserveWhiteSpace=false;
$dom->loadXML( $xml );
$errors = libxml_get_errors();
libxml_clear_errors();




$xp=new DOMXPath( $dom );
$col=$xp->query( '//Products/Product' );
if( $col->length > 0 ){

    foreach( $col as $node ){

        /* Get the `productname` and create a new element before with same value */
        $productname=$xp->query( 'productname', $node )->item(0);
        $newproductname=$dom->createElement( 'newproductname', $productname->textContent );
        $node->insertBefore( $newproductname, $productname );

        /* Find all the Image tags within parent */
        $ref=$xp->query( 'Image', $node );

        /* determine reference node to use for `insertBefore` */
        if( $ref && $ref->length > 0 )$refNode=$ref->item(0);
        else $refNode=$node->lastChild;

        /* create a new `Images` node */
        $oImages=$dom->createElement('Images');
        $node->insertBefore( $oImages, $refNode );

        /* using previously discovered `Image` nodes, add to the new `Images` element */
        foreach( $ref as $img )$oImages->appendChild( $img );
    }
}

/* for demo display */
printf('<pre>%s
', print_r (htmlentities ($ dom-> saveXML ()), true));/ * Для реального вывода * / #header ('Content-Type: application / xml');#exit ($ dom-> saveXML ());

Вывод отладочной печати (printf выше) выглядит следующим образом и, как я полагаю, следует желаемому формату вывода - кроме нового, не упомянутого тега newsku, который вы показываете выше:

<?xml version="1.0" encoding="UTF-8"?>
<Root>
  <Products>
    <Product>
      <newproductname> pr_name 1</newproductname>
      <productname> pr_name 1</productname>
      <price> pr_price 1</price>
      <sku> pr_sku 1</sku>
      <Images>
        <Image> image_url 1.1</Image>
        <Image> image_url 1.2</Image>
      </Images>
    </Product>
    <Product>
      <newproductname> pr_name 2</newproductname>
      <productname> pr_name 2</productname>
      <price> pr_price 2</price>
      <sku> pr_sku 2</sku>
      <Images>
        <Image> image_url 2</Image>
      </Images>
    </Product>
    <Product>
      <newproductname> pr_name 3</newproductname>
      <productname> pr_name 3</productname>
      <price> pr_price 3</price>
      <sku> pr_sku 3</sku>
      <Images>
        <Image> image_url 3.1</Image>
        <Image> image_url 3.2</Image>
        <Image> image_url 3.3</Image>
      </Images>
    </Product>
    <Product>
      <newproductname> pr_name 4</newproductname>
      <productname> pr_name 4</productname>
      <price> pr_price 4</price>
      <Images/>
      <sku> pr_sku 4</sku>
    </Product>
  </Products>
</Root>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...