Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/231.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
标识XML元素并使用PHP将父节点复制到外部XML文件_Php_Xml_Domdocument - Fatal编程技术网

标识XML元素并使用PHP将父节点复制到外部XML文件

标识XML元素并使用PHP将父节点复制到外部XML文件,php,xml,domdocument,Php,Xml,Domdocument,我正在用PHP解析一个XML文件(source.XML),需要识别节点包含元素的实例 一旦识别出该条目的整个父节点,就应该将其复制到单独的XML文件(destination.XML)中 复制完成后,应将节点从source.xml文件中删除 下面是source.xml文件的示例: <?xml version="1.0" encoding="utf-8"?> <root> <property> ... <rent>

我正在用PHP解析一个XML文件(source.XML),需要识别
节点包含
元素的实例

一旦识别出该条目的整个
父节点,就应该将其复制到单独的XML文件(destination.XML)中

复制完成后,应将
节点从source.xml文件中删除

下面是source.xml文件的示例:

<?xml version="1.0" encoding="utf-8"?>
<root>
    <property>
        ...
        <rent>
            <term>long</term>
            <freq>month</freq>
            <price_peak>1234</price_peak>
            <price_high>1234</price_high>
            <price_medium>1234</price_medium>
            <price_low>1234</price_low>
        </rent>
        ...
    </property>
</root>

我才刚刚开始了解DOMDocument及其用途,所以我显然在某个地方搞砸了,所以非常感谢您的帮助。非常感谢。

困难在于您试图将节点从一个文档复制到另一个文档。您可以尝试重新创建节点,跨多个节点复制所有组件,但这是一项艰巨的工作(而且容易出错)。相反,您可以使用
importNode
将节点从一个文档导入到另一个文档。第二个参数表示复制所有子元素

然后从原始文档中删除元素就是让项目“从其父项中删除自身”,这听起来很奇怪,但这就是代码的工作方式

<?php
error_reporting ( E_ALL );
ini_set ( 'display_errors', 1 );

$destination = new DOMDocument;
$destination->preserveWhiteSpace = true;
$destination->loadXML('<?xml version="1.0" encoding="utf-8"?><root></root>');

$source = new DOMDocument;
$source->load('NewFile.xml');

$xp = new DOMXPath($source);
$destRoot = $destination->getElementsByTagName("root")->item(0);
foreach ($xp->query('/root/property[rent]') as $item) {
    $newItem = $destination->importNode($item, true);
    $destRoot->appendChild($newItem);
    $item->parentNode->removeChild($item);
}

echo "Source:".$source->saveXML();
$destination->formatOutput = true;
echo "destination:".$destination->saveXml();
load('NewFile.xml');
$xp=新的DOMXPath($source);
$destRoot=$destination->getElementsByTagName(“根”)->项(0);
foreach($xp->query('/root/property[rent]')作为$item){
$newItem=$destination->importNode($item,true);
$desroot->appendChild($newItem);
$item->parentNode->removeChild($item);
}
echo“Source:”.$Source->saveXML();
$destination->formatOutput=true;
echo“destination:”.$destination->saveXml();

对于目的地,我使用basic
元素初始化它,然后从那里添加内容。

您想获得类似的内容吗?希望这有助于:

$inXmlFile = getcwd() . "/source.xml";
$inXmlString = file_get_contents($inXmlFile);
$outXmlFile = getcwd() . "/destination.xml";
$outXmlString = file_get_contents($outXmlFile);

$sourceDOMDocument = new DOMDocument;
$sourceDOMDocument->loadXML($inXmlString);

$sourceRoot = null;
foreach ($sourceDOMDocument->childNodes as $childNode) {
    if(strcmp($childNode->nodeName, "root") == 0) {
        $sourceRoot = $childNode;
        break;
    }
}

$destDOMDocument = new DOMDocument;
$destDOMDocument->loadXML($outXmlString);

$destRoot = null;
foreach ($destDOMDocument->childNodes as $childNode) {
    if(strcmp($childNode->nodeName, "root") == 0) {
        $destRoot = $childNode;
        break;
    }
}

$xmlStructure = simplexml_load_string($inXmlString);

$domProperty = dom_import_simplexml($xmlStructure->property);

$rents = $domProperty->getElementsByTagName('rent');
if(($rents != null) && (count($rents) > 0)) {
    $destRoot->appendChild($destDOMDocument->importNode($domProperty->cloneNode(true), true));
    $destDOMDocument->save($outXmlFile);
    $sourceRoot->removeChild($sourceRoot->getElementsByTagName('property')->item(0));
    $sourceDOMDocument->save($inXmlFile);
}

考虑运行两个XSLT转换:一个在目标中添加
节点,另一个从源中删除这些节点。作为背景,是一种特殊用途的语言,设计用于转换XML文件,甚至可以维护
document()
函数来解析同一文件夹或子文件夹中的外部XML文件

PHP可以使用其类运行XSLT1.0脚本(请确保在.ini文件中启用扩展名)。使用这种方法,不需要
if
逻辑或
foreach
循环

XSLT脚本

PropertyRentAdd.xsl(确保source.xml和XSLT位于同一文件夹中)


输入(示例演示,其他标签显示内容不受影响)

source.xml

<?xml version="1.0" encoding="utf-8"?>
<root>
    <property>
        <rent>
            <term>long</term>
            <freq>month</freq>
            <price_peak>1234</price_peak>
            <price_high>1234</price_high>
            <price_medium>1234</price_medium>
            <price_low>1234</price_low>
        </rent>
    </property>
    <property>
        <rent>
            <term>short</term>
            <freq>month</freq>
            <price_peak>7890</price_peak>
            <price_high>7890</price_high>
            <price_medium>7890</price_medium>
            <price_low>7890</price_low>
        </rent>
    </property>
    <property>
        <web_site>stackoverflow</web_site>
        <general_purpose>php</general_purpose>
    </property>
    <property>
        <web_site>stackoverflow</web_site>
        <special_purpose>xsl</special_purpose>
    </property>
</root>

长的
月
1234
1234
1234
1234
短的
月
7890
7890
7890
7890
栈溢出
php
栈溢出
xsl
destination.xml

<?xml version="1.0" encoding="utf-8"?>
<root>
    <original_data>
        <test1>ABC</test1>
        <test2>123</test2>
    </original_data>
    <original_data>
        <test1>XYZ</test1>
        <test2>789</test2>
    </original_data>
</root>

基础知识
123
XYZ
789
输出(PHP运行后)

source.xml

<?xml version="1.0"?>
<root>
  <property>
    <web_site>stackoverflow</web_site>
    <general_purpose>php</general_purpose>
  </property>
  <property>
    <web_site>stackoverflow</web_site>
    <special_purpose>xsl</special_purpose>
  </property>
</root>

栈溢出
php
栈溢出
xsl
destination.xml(在底部追加新节点)


基础知识
123
XYZ
789
长的
月
1234
1234
1234
1234
短的
月
7890
7890
7890
7890

非常感谢。这非常有效,除了源输出和目标输出都不会保存到仅输出到控制台的文件中。我试着摆弄它来生成文件,但没有结果。如何将$source输出到newsource.xml和$destination输出到destination.xml?没关系,我知道了:)。我尝试的是$source->saveXML(“final_source.xml”),而不是直接的$source->save(“final_source.xml”)。再次感谢。谢谢你的工作冻糕,它非常详细,我一定会调查。然而,就目前而言,Nigel Ren给出的答案更符合我的工作流程。再次感谢。
// Set current path
$cd = dirname(__FILE__);

// Load the XML and XSLT files
$doc = new DOMDocument();
$doc->load($cd.'/destination.xml');     

$xsl = new DOMDocument;
$xsl->load($cd.'/PropertRentAdd.xsl');

// Transform the destination xml
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);     
$newXml = $proc->transformToXML($xml);

// Save output to file, overwriting original
file_put_contents($cd.'/destination.xml', $newXml);


// Load the XML and XSLT files
$doc = new DOMDocument();
$doc->load($cd.'/source.xml');

$xsl = new DOMDocument;
$xsl->load($cd.'/PropertRentRemove.xsl');

// Transform the source xml
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);     
$newXml = $proc->transformToXML($xml);

// Save output overwriting original file
file_put_contents($cd.'/source.xml', $newXml);
<?xml version="1.0" encoding="utf-8"?>
<root>
    <property>
        <rent>
            <term>long</term>
            <freq>month</freq>
            <price_peak>1234</price_peak>
            <price_high>1234</price_high>
            <price_medium>1234</price_medium>
            <price_low>1234</price_low>
        </rent>
    </property>
    <property>
        <rent>
            <term>short</term>
            <freq>month</freq>
            <price_peak>7890</price_peak>
            <price_high>7890</price_high>
            <price_medium>7890</price_medium>
            <price_low>7890</price_low>
        </rent>
    </property>
    <property>
        <web_site>stackoverflow</web_site>
        <general_purpose>php</general_purpose>
    </property>
    <property>
        <web_site>stackoverflow</web_site>
        <special_purpose>xsl</special_purpose>
    </property>
</root>
<?xml version="1.0" encoding="utf-8"?>
<root>
    <original_data>
        <test1>ABC</test1>
        <test2>123</test2>
    </original_data>
    <original_data>
        <test1>XYZ</test1>
        <test2>789</test2>
    </original_data>
</root>
<?xml version="1.0"?>
<root>
  <property>
    <web_site>stackoverflow</web_site>
    <general_purpose>php</general_purpose>
  </property>
  <property>
    <web_site>stackoverflow</web_site>
    <special_purpose>xsl</special_purpose>
  </property>
</root>
<?xml version="1.0"?>
<root>
  <original_data>
    <test1>ABC</test1>
    <test2>123</test2>
  </original_data>
  <original_data>
    <test1>XYZ</test1>
    <test2>789</test2>
  </original_data>
  <property>
    <rent>
      <term>long</term>
      <freq>month</freq>
      <price_peak>1234</price_peak>
      <price_high>1234</price_high>
      <price_medium>1234</price_medium>
      <price_low>1234</price_low>
    </rent>
  </property>
  <property>
    <rent>
      <term>short</term>
      <freq>month</freq>
      <price_peak>7890</price_peak>
      <price_high>7890</price_high>
      <price_medium>7890</price_medium>
      <price_low>7890</price_low>
    </rent>
  </property>
</root>