在PHP中分割XML

6
我有一个包含根元素和多个子元素的合并XML文件。 类似这样:
 <root>
  <item>test1</item>
  <item>test2</item>
 </root>

今日免费次数已满, 请开通会员/明日再来
$arrXml[0] = '<item>test1</item>';
$arrXml[1] = '<item>test2</item>';

我正在寻找一种优雅的解决方案,而不是任何解决方案。

我不明白这与什么相关?我有一个特定的任务需要这个特定的解决方案。我认为整体情况不能改变。我相信在需求方面我已经表达得很清楚了。 - johnlemon
@user 这听起来就像是一个非常愚蠢的想法。 - Pekka
2
元素是否会在同一行上开始和结束?从您的大局来看,我认为这种方法最好使用XSLT解决,或者至少不要转换为数组。我的意思是,如果您需要发送XML回来,为什么要转换为数组?只需选择所需部分并将它们发送即可。顺便说一句,好问题,Pekka问得好。 - Gordon
我也需要拆分XML。在系统集成平台(如ESB)中,转换XML是一项常见任务。danip提出了一个很好的问题。 - xmedeko
显示剩余3条评论
3个回答

7

好的,就像在您的问题评论中已经提到的那样,我不认为这是您应该做的,但由于我不能忍受SimpleXml并且不希望人们认为这是唯一的方法,下面是如何使用DOM实现:

$arrXml = array();
$dom    = new DOMDocument;
$dom->loadXML( $xml );
foreach( $dom->getElementsByTagName( 'item' ) as $item ) {
    $arrXml[] = $dom->saveXML( $item );
}
print_r( $arrXml );

使用 XMLReader

$arrXml = array();
$reader = new XmlReader;
$reader->xml( $xml );
while( $reader->read() ) {
    if( $reader->localName === 'item' && $reader->nodeType === 1 ) {
        $arrXml[] = $reader->readOuterXml();
    }
}
print_r( $arrXml );

并且 XMLParser*:

xml_parse_into_struct(xml_parser_create(), $xml, $nodes);
$xmlArr = array();
foreach($nodes as $node) {
    if($node['tag'] === 'ITEM') {
        $arrXml[] = "<item>{$node['value']}</item>";
    }
}
print_r($arrXml);

*也可以通过在遇到ITEM元素时触发回调来完成此操作。需要更多的代码,但非常灵活。

请注意,以上所有内容可能需要根据您实际的XML进行一些微调。


考虑到您问题中的XML(很可能只是一个示例)非常简单且定义良好,您还可以使用explode()

$arrXml = array_map( 'trim',
    array_filter(
        explode( PHP_EOL, $xml ),
        function( $line ) { return substr( $line, 0, 6 ) === '<item>'; }
));
print_r( $arrXml );

或者使用正则表达式(请阅读免责声明)。
preg_match_all('#<item>.*</item>#', $xml, $arrXml);
print_r($arrXml[0]);

免责声明 现在,只是为了确保您不会经常使用正则表达式或分解来解析XML:只有当您的标记确实像您展示的那样明确定义时,最后两种方法才可行。


您没有提到SimpleXmlElement,它可以进行xpath查找。但根据我的经验,它的asXml()方法不能很好地处理命名空间。 - xmedeko

2

SimpleXml手册页面的评论中有一些不错的代码示例。我相信你可以从objectsIntoArray()示例中获得一些灵感。


1
你看过SimpleXML吗?
例如:
$string = "
 <root>
  <item>test1</item>
  <item>test2</item>
 </root>
";

$xml = simplexml_load_string($string);

这不会给他他所要求的东西。话虽如此,我不确定他所要求的是否是一个好主意。 - Pekka
@Pekka - 是的,我知道,但他想要一种优雅的解决方案来解析XML,而simpleXML就是这样的(在我看来)。否则容易出现太多错误。 - robjmills
1
这是第一步,我同意...但剩下的呢? - johnlemon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接