我需要使用PHP代码更改文本在XML文件中。然后,我创建了一个代码:
1 - 获取文件
2-替换文本
3-保存与其他名称的文件。
问题是,我有一些问题,以取代在一个XML文件中的一些文本。
我能够取代simples字符串,但我不能像字符替换文本“<”。下面真正的代码和文件。
原始XML路径:http://www.csainmobiliaria.com/imagenes/fotos/pisos-NOK.xml
1)该代码只是改变了文本Inmuebles
到xxxxxxxx
。这工作正常
$xml_external_path = 'http://www.csainmobiliaria.com/imagenes/fotos/pisos-NOK.xml';
$xml = file_get_contents($xml_external_path);
$response = strtr($xml, array(
'Inmuebles' => 'xxxxxxxx'
));
$newXml = $response;
$newXml = simplexml_load_string( $newXml );
$newXml->asXml('/home/csainmobiliaria/www/pisos-NEW.xml');
2)现在,如果我用这个代码更改文本<Table Name="Inmuebles">
到<xxxxxxxx>
我得到一个错误500。
$xml_external_path = 'http://www.csainmobiliaria.com/imagenes/fotos/pisos-NOK.xml';
$xml = file_get_contents($xml_external_path);
$response = strtr($xml, array(
'<Table Name="Inmuebles">' => '<xxxxxxxx>'
));
$newXml = $response;
$newXml = simplexml_load_string( $newXml );
$newXml->asXml('/home/csainmobiliaria/www/pisos-NEW.xml');
3)以同样的方式,如果我用这个代码删除文本Publicacion
我得到一个错误500。
$xml_external_path = 'http://www.csainmobiliaria.com/imagenes/fotos/pisos-NOK.xml';
$xml = file_get_contents($xml_external_path);
$response = strtr($xml, array(
'<Publicacion>' => ''
));
$newXml = $response;
$newXml = simplexml_load_string( $newXml );
$newXml->asXml('/home/csainmobiliaria/www/pisos-NEW.xml');
这是最后的结果,我需要得到:http://www.csainmobiliaria.com/imagenes/fotos/pisos-OK.xml
DOMDocument允许复制节点的结构,所以,而不是必须所有的细节单独复制(其可以容易丢失的数据的规范发生变化时),则可以从一个文档复制整个节点(如<Inmueble>
)到另一个使用importNode()
其具有参数,以指示该元件的全部内容应该被复制。这种方法还可以复制任何使用相同的功能,无需更改代码的表...
function extractData ( $sourceFile, $table ) {
// Load source data
$source = new DOMDocument();
$source->load($sourceFile);
$xp = new DOMXPath($source);
// Create new data document
$newFile = new DOMDocument();
$newFile->formatOutput = true;
// Create base element with the table name in new document
$newRoot = $newFile->createElement($table);
$newFile->appendChild($newRoot);
// Find the records to copy
$records = $xp->query('//Table[@Name="'.$table.'"]/*');
foreach ( $records as $record ) {
// Import the node to copy and append it to new document
$newRoot->appendChild();
}
// Return the source of the XML
return $newFile->saveXML();
}
echo extractData ($xml_external_path, "Inmuebles");
你可以改变返回文档作为DOM文档,甚至是SimpleXML的版本,如果你想进一步处理它的方法。
对于SimpleXML的,改回...
return simplexml_import_dom($newRoot);
然后你就可以把它作为...
$ret = extractData ($xml_external_path, "Inmuebles");
echo $ret->asXML();
或者,如果你只是想这样做的固定方式,可以去除XPath和只使用getElementsByTagName()
找到节点复制...
$source = new DOMDocument();
$source->load($xml_external_path);
$newFile = new DOMDocument();
$newRoot = $newFile->createElement("Inmuebles");
$newFile->appendChild($newRoot);
// Find the records to copy
foreach ( $source->getElementsByTagName("Inmueble") as $record ) {
$newRoot->appendChild($newFile->importNode($record, true));
}
echo $newFile->saveXML();
要添加保存的文件名,我已经加入到功能的新参数,这个新功能不返回任何东西 - 它只是加载该文件,并将结果保存到新的文件名...
function extractData ( $sourceFile, $table, $newFileName ) {
// Load source data
$source = new DOMDocument();
$source->load($sourceFile);
$xp = new DOMXPath($source);
// Create new file document
$newFile = new DOMDocument();
$newFile->formatOutput = true;
// Create base element with the table name in new document
$newRoot = $newFile->createElement($table);
$newFile->appendChild($newRoot);
// Find the records to copy
$records = $xp->query('//Table[@Name="'.$table.'"]/*');
foreach ( $records as $record ) {
// Import the node to copy and append it to new document
$importNode = $newFile->importNode($record, true);
// Add new content
$importNode->appendChild($newFile->createElement("Title", "value"));
$newRoot->appendChild();
}
// Update Foto elements
$xp = new DOMXPath($newFile);
$fotos = $xp->query("//*[starts-with(local-name(), 'Foto')]");
foreach ( $fotos as $foto ) {
$path = $foto->nodeValue;
if( substr($path, 0, 5) == "/www/" ) {
$path = substr($path,4);
}
// Replace node with new version
$foto->parentNode->replaceChild($newFile->createElement("Foto1", $path),
$foto);
}
$newFile->save($newFileName);
}
$xml_external_path = 'http://www.csainmobiliaria.com/imagenes/fotos/pisos.xml';
$xml_external_savepath = 'saveFile.xml';
extractData ($xml_external_path, "Inmuebles", $xml_external_savepath);
您可以复制,而不是删除任何多余的元素的必要节点。例如,您可以复制与帮助的SimpleXML Inmuebles
节点:
$path = 'http://www.csainmobiliaria.com/imagenes/fotos/pisos-NOK.xml';
$content = file_get_contents($path);
$sourceXML = new SimpleXMLElement($content);
$targetXML = new SimpleXMLElement("<Inmuebles></Inmuebles>");
$items = $sourceXML->xpath('Table[@Name=\'Inmuebles\']');
foreach ($items as $item) {
foreach ($item->Inmueble as $inmueble) {
$node = $targetXML->addChild('Inmueble');
$node->addChild('IdInmobiliariaExterna', $inmueble->IdInmobiliariaExterna);
$node->addChild('IdPisoExterno', $inmueble->IdPisoExterno);
$node->addChild('FechaHoraModificado', $inmueble->FechaHoraModificado);
$node->addChild('TipoInmueble', $inmueble->TipoInmueble);
$node->addChild('TipoOperacion', $inmueble->TipoOperacion);
}
}
echo $targetXML->asXML()
此外,如在@ThW评论说,你可以使用XLST,例如:
$path = 'http://www.csainmobiliaria.com/imagenes/fotos/pisos-NOK.xml';
$content = file_get_contents($path);
$sourceXML = new SimpleXMLElement($content);
$xslt='<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Table[@Name=\'Inmuebles\']">
<Inmuebles>
<xsl:copy-of select="node()"/>
</Inmuebles>
</xsl:template>
<xsl:template match="Table[@Name=\'Agencias\']"/>
</xsl:stylesheet>';
$xsl = new SimpleXMLElement($xslt);
$processor = new XSLTProcessor;
$processor->importStyleSheet($xsl);
$result = $processor->transformToXML($sourceXML);
$targetXML = new SimpleXMLElement($result);
echo $targetXML->asXML();
再考虑,XSLT,W3C的标准兼容,专用语言设计修改XML文件需要用户规范,如您的#1-3的需求。像其他流行的声明性语言,SQL,XSLT不限于PHP,但移植到其他应用程序层(Java,C#,Python和Perl中,R)和专用XSLT 1.0, 2.0, and 3.0 .exe processors。
通过这种方法,XSLT的递归的造型可以让你避免任何foreach
循环,if
逻辑和重复线,如addChild
或在应用层调用appendChild
。
XSLT(另存为.xsl文件一,一个特殊的.xml文件,或嵌入字符串;移植到PHP之外其他接口)
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/>
<xsl:strip-space elements="*"/>
<!-- WALK DOWN TREE FROM ROOT -->
<xsl:template match="Publication">
<xsl:apply-templates select="Table"/>
</xsl:template>
<xsl:template match="Table[@Name='Inmuebles']">
<Inmuebles>
<xsl:apply-templates select="*"/>
</Inmuebles>
</xsl:template>
<!-- EMPTY TEMPLATE TO REMOVE SPECIFIED NODES -->
<xsl:template match="Table[@Name='Agencias']"/>
<!-- RETURN ONLY FIRST FIVE NODES -->
<xsl:template match="Table/*">
<Inmuebles>
<xsl:copy-of select="*[position() <= 5]"/>
</Inmuebles>
</xsl:template>
</xsl:stylesheet>
PHP(使用php_xsl
库)
// LOAD XML SOURCE
$url = 'http://www.csainmobiliaria.com/imagenes/fotos/pisos-NOK.xml';
$web_data = file_get_contents($url);
$xml = new SimpleXMLElement($web_data);
// LOAD XSL SCRIPT
$xsl = simplexml_load_file('/path/to/script.xsl');
// XSLT TRANSFORMATION
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
$newXML = $proc->transformToXML($xml);
// OUTPUT TO CONSOLE
echo $newXML;
// SAVE TO FILE
file_put_contents('Output.xml', $newXML);
正如伟大的XSLT大师,@Dimitre Novatchev,通常结束了他的职位:想要的,正确的结果产生:
<?xml version="1.0" encoding="ISO-8859-1"?>
<Inmuebles>
<Inmuebles>
<IdInmobiliariaExterna>B45695855</IdInmobiliariaExterna>
<IdPisoExterno>100002</IdPisoExterno>
<FechaHoraModificado>30/11/2018</FechaHoraModificado>
<TipoInmueble>PISO</TipoInmueble>
<TipoOperacion>3</TipoOperacion>
</Inmuebles>
<Inmuebles>
<IdInmobiliariaExterna>B45695855</IdInmobiliariaExterna>
<IdPisoExterno>100003</IdPisoExterno>
<FechaHoraModificado>30/11/2018</FechaHoraModificado>
<TipoInmueble>CHALET</TipoInmueble>
<TipoOperacion>4</TipoOperacion>
</Inmuebles>
</Inmuebles>