Как скопировать родительские узлы в текущий узел SimpleXml - PullRequest
0 голосов
/ 15 мая 2018

Я хочу разбить XML на более мелкие куски для дальнейшей обработки.Чтобы быть самодостаточным для импорта, каждый блок должен содержать всю информацию, находящуюся за пределами их области действия.

Допустим, я настраиваю в качестве нового, полностью содержащего корня:

<ROOT>
    <SUBROOT>
        <MOVEME>moveme</MOVEME>
        <ITEM>
            <AAA>111</AAA>
        </ITEM>
        <ITEM>
            <AAA>111</AAA>
        </ITEM>
    </SUBROOT>
</ROOT>

должно стать

<NEWROOT>
        <ITEM>
            <MOVEME>moveme</MOVEME>
            <AAA>111</AAA>
        </ITEM>
        <ITEM>
            <MOVEME>moveme</MOVEME>
            <AAA>111</AAA>
        </ITEM>
</NEWROOT>

Каким будет высокопроизводительное решение?Спасибо!

1 Ответ

0 голосов
/ 16 мая 2018

Рассмотрим XSLT (родственный XPath), язык специального назначения, предназначенный для преобразования файлов XML в другие файлы XML, HTML и даже текстовые файлы.PHP может запускать сценарии XSLT 1.0 со своим классом php-xsl (обязательно включите его в файле .ini).

Для XML-файлов малого и среднего размера XSLT является производительным вариантом, поскольку вы даже избегаете циклов foreach и логики if и дерева перестроения (т. Е. importNode) на уровне приложения.В частности, ниже XSLT анализирует до уровня ITEM и сопоставляет родительский SUBROOT необходимый элемент, используя XPath's ancestor::*.Настройте в скрипте фактические имена узлов.

XSLT (сохранить как файл .xsl, специальный файл .xml)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/ROOT">   
        <NEWROOT>
            <xsl:apply-templates select="SUBROOT"/>
        </NEWROOT>
    </xsl:template>

    <xsl:template match="SUBROOT">      
        <xsl:apply-templates select="ITEM"/>
    </xsl:template>

    <xsl:template match="ITEM">
        <xsl:copy>
            <xsl:copy-of select="ancestor::SUBROOT/MOVEME" />
            <xsl:copy-of select="*"/>
        </xsl:copy>
    </xsl:template>
</xsl:transform>

PHP

# LOAD XML AND XSL FILES
$xml = new DOMDocument;
$xml->load('/path/to/input.xml');

$xsl = new DOMDocument;
$xsl->load('/path/to/xslt_script.xsl');

// CONFIGURE TRANSFORMER
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);

// RUN TRANSFORMATION
$newXML = new DOMDocument;
$newXML = $proc->transformToXML($xml);

// OUTPUT NEW XML
echo $newXML;

// SAVE NEW DOM TREE TO FILE
file_put_contents('/path/to/output.xml', $newXML);

XSLT Demo

...