我正在尝试将XML文件分成两个文件,longrentals.xml和shortrentals.xml,但是我遇到了最后一个障碍。以下是我想要发生的事情:
XML结构如下:
<property>
...
<rent>
<term>short</term>
<freq>week</freq>
<price_peak>5845</price_peak>
<price_high>5845</price_high>
<price_medium>4270</price_medium>
<price_low>3150</price_low>
</rent>
...
</property>
我正在使用的代码如下:
$destination = new DOMDocument;
$destination->preserveWhiteSpace = true;
$destination->loadXML('<?xml version="1.0" encoding="utf-8"?><root></root>');
$source = new DOMDocument;
$source->load('file/rentals.xml');
$xp = new DOMXPath($source);
$destRoot = $destination->getElementsByTagName("root")->item(0);
foreach ($xp->query('/root/property/rent[term = "short"]') as $item) {
$newItem = $destination->importNode($item, true);
$destRoot->appendChild($newItem);
$item->parentNode->removeChild($item);
}
$source->save("file/longrentals.xml");
$destination->formatOutput = true;
$destination->save("file/shortrentals.xml");
除了shortrentals.xml中的输出只包含rent节点而不是顶级父Property节点之外,这是有效的。 longrentals.xml中删除的条目也只删除了Rent子节点。那么,我如何使用我的代码升级?
答案 0 :(得分:1)
您可以使用DOMNode的parentNode
属性在结构中上升一级(类似于removeChild
代码中的操作方式)...
foreach ($xp->query('/root/property/rent[term = "short"]') as $item) {
$property = $item->parentNode;
$newItem = $destination->importNode($property, true);
$destRoot->appendChild($newItem);
$property->parentNode->removeChild($property);
}
答案 1 :(得分:0)
或者,考虑使用专用XML转换语言XSLT来创建没有foreach
循环的XML文件。这里,XSLT作为字符串嵌入,但可以像任何其他XML文件一样从文件中解析。假定的XML结构:<root><property><rent>...
shortrentals.xml 输出
// Load XML and XSL sources
$xml = new DOMDocument;
$xml->load('file/rentals.xml');
$xslstr = '<?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="*"/>
<xsl:template match="/root">
<xsl:copy>
<xsl:apply-templates select="property[rent/term=\'short\']"/>
</xsl:copy>
</xsl:template>
<xsl:template match="property">
<xsl:copy>
<xsl:copy-of select="*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>';
$xsl = new DOMDocument;
$xsl->loadXML($xslstr);
// Configure transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// Transform XML source
$newXML = new DOMDocument;
$newXML = $proc->transformToXML($xml);
// Output file
file_put_contents('file/shortrentals.xml', $newXML);
longrentals.xml (使用Identity Transform和空模板删除节点)
// Load XML and XSL sources
$xml = new DOMDocument;
$xml->load('file/rentals.xml');
$xslstr = '<?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="*"/>
<!-- Identity Transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Remove Non-Short Terms -->
<xsl:template match="property[rent/term=\'short\']"/>
</xsl:stylesheet>';
$xsl = new DOMDocument;
$xsl->loadXML($xslstr);
// Configure transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// Transform XML source
$newXML = new DOMDocument;
$newXML = $proc->transformToXML($xml);
// Output file
file_put_contents('file/longrentals.xml', $newXML);