Изменить значение элемента в SimpleXML при поиске по xpath по значению атрибута - PullRequest
0 голосов
/ 03 сентября 2018

Изменить элемент с SimpleXML xpath

Я хочу изменить значение элемента путем поиска xpath после определенного атрибута.

У меня есть XML-файл, в котором я хочу изменить значение всех элементов с атрибутом «Нет»

<Value1>
        <Type No="001">ABC</Type>
</Value1>
    <Value2>
        <Type No="002">CDE</Type>
        <ID No="003">DEF</ID>
        <ShareID No="004">GFH</ShareID>
    </Value2>
    ...
    ...

В PHP я написал скрипт, который должен искать все элементы с атрибутом «Нет» и изменять значение с помощью заданной таблицы Json. Внутри таблицы у меня есть пары с идентификатором и значением.

В качестве первого прототипа я только что написал скрипт, который изменяет первый элемент с номером = '001' на «Тест»;

<?php

$data = file_get_contents( "php://input" ); //$data is now the string '[1,2,3]';

$data = json_decode( $data ); //$data is now a php array array(1,2,3)

$test = $data->data;

// load the document

// Load XML File 
$xml = simplexml_load_file($data->xmlFile);

//TODO Change each Element which is in the JSON Table

$result  = $xml->xpath("//*[@No='001']");

// TODO Change every Element by corresponding JSON Table

$result[0] = "Test";

// save the updated document
$xml->asXML($data->xmlFile);

echo "OK";

?>

В результате из функции xpath я получаю следующий массив:

    SimpleXMLElement
        @attributes:array(1)
            0:"ABC"

Способ, которым я получаю доступ к результату выше, не работает. Как я могу получить доступ к значению элемента ("ABC") в SimpleXMLElement в результате запроса xpath? Я продолжаю развитие, я хочу

1 Ответ

0 голосов
/ 03 сентября 2018

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

Ниже демонстрируется настройка для одного элемента типа с условием @No='001' со значением параметра, переданным из PHP. Вы можете расширить количество параметров и шаблонов по мере необходимости. Identity Transform копирует весь документ, как и раньше, до ваших настроек.

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

<?xml version="1.0" ?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">  
   <xsl:output method="xml" indent="yes"/>
   <xsl:strip-space elements="*"/>

   <!-- Initializing Parameters -->
   <xsl:param name="php_param"/>

    <!-- Identity Transform -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- Assign New Text Value by Parameter -->
    <xsl:template match="Type[@No='001']">
        <xsl:copy>
            <xsl:copy-of select="@*" />
            <xsl:value-of select="$php_param"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

PHP

...

// LOAD XML
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->load($data->xmlFile);

// LOAD XSLT 
$xsl = new DOMDocument('1.0', 'UTF-8');   
$xsl->load('XSLT_Script.xsl');

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

// SET PARAMETER VALUE
$proc->setParameter('', 'php_param', 'test');

// TRANSFORM SOURCE
$newXML = $proc->transformToDoc($xml);

// SAVE TO FILE
file_put_contents($data->xmlFile, $newXML);
...