Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/286.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
Php 如何对使用SimpleXML加载的XML文件的内容进行排序?_Php_Xml_Sorting - Fatal编程技术网

Php 如何对使用SimpleXML加载的XML文件的内容进行排序?

Php 如何对使用SimpleXML加载的XML文件的内容进行排序?,php,xml,sorting,Php,Xml,Sorting,有一个XML文件,其内容类似于以下内容: <FMPDSORESULT xmlns="http://www.filemaker.com"> <ERRORCODE>0</ERRORCODE> <DATABASE>My_Database</DATABASE> <LAYOUT/> <ROW MODID="1" RECORDID="1"> <Name>John</Name> <

有一个XML文件,其内容类似于以下内容:

<FMPDSORESULT xmlns="http://www.filemaker.com">
<ERRORCODE>0</ERRORCODE>
<DATABASE>My_Database</DATABASE>
<LAYOUT/>
<ROW MODID="1" RECORDID="1">
    <Name>John</Name>
    <Age>19</Age>
</ROW>
<ROW MODID="2" RECORDID="2">
    <Name>Steve</Name>
    <Age>25</Age>
</ROW>
<ROW MODID="3" RECORDID="3">
    <Name>Adam</Name>
    <Age>45</Age>
</ROW>

但是代码没有按预期工作。

一些SimpleXMLElement方法返回数组,但大多数返回实现迭代器的SimpleXMLElement对象。var_dump()将仅以简化的表示形式显示部分数据。但是,它是一个对象结构,而不是嵌套数组

如果我理解正确,您希望按
名称
子元素对
元素进行排序。可以使用
xpath()
方法获取它们,但需要为名称空间注册前缀。它返回一个SimpleXMLElement对象数组。可以使用
usort
对数组进行排序

$fResult = new SimpleXMLElement($xml);
$fResult->registerXpathNamespace('fm', 'http://www.filemaker.com');
$rows = $fResult->xpath('//fm:ROW');

usort(
  $rows,
  function(SimpleXMLElement $one, SimpleXMLElement $two) {
    return strcasecmp($one->Name, $two->Name);
  }
);

var_dump($rows);
在DOM中,它看起来没有太大的不同,但是
DOMXpath::evaluate()
返回一个
DOMNodeList
。您可以使用
迭代器\u to\u array
将其转换为数组

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('fm', 'http://www.filemaker.com');

$rows = iterator_to_array($xpath->evaluate('//fm:ROW'));

usort(
  $rows,
  function(DOMElement $one, DOMElement $two) use ($xpath) {
    return strcasecmp(
      $xpath->evaluate('normalize-space(Name)', $one),
      $xpath->evaluate('normalize-space(Name)', $two)
    );
  }
);

var_dump($rows);

DOM没有访问子对象和值的神奇方法,可以使用Xpath获取它们。Xpath函数
string()
将第一个节点转换为字符串。如果节点列表为空,则返回空字符串
normalize-space()
做的更多。它用一个空格替换所有的空白组,并将其从字符串的开头和结尾剥离。

一些SimpleXMLElement方法返回数组,但大多数返回实现迭代器的SimpleXMLElement对象。var_dump()将仅以简化的表示形式显示部分数据。但是,它是一个对象结构,而不是嵌套数组

如果我理解正确,您希望按
名称
子元素对
元素进行排序。可以使用
xpath()
方法获取它们,但需要为名称空间注册前缀。它返回一个SimpleXMLElement对象数组。可以使用
usort
对数组进行排序

$fResult = new SimpleXMLElement($xml);
$fResult->registerXpathNamespace('fm', 'http://www.filemaker.com');
$rows = $fResult->xpath('//fm:ROW');

usort(
  $rows,
  function(SimpleXMLElement $one, SimpleXMLElement $two) {
    return strcasecmp($one->Name, $two->Name);
  }
);

var_dump($rows);
在DOM中,它看起来没有太大的不同,但是
DOMXpath::evaluate()
返回一个
DOMNodeList
。您可以使用
迭代器\u to\u array
将其转换为数组

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('fm', 'http://www.filemaker.com');

$rows = iterator_to_array($xpath->evaluate('//fm:ROW'));

usort(
  $rows,
  function(DOMElement $one, DOMElement $two) use ($xpath) {
    return strcasecmp(
      $xpath->evaluate('normalize-space(Name)', $one),
      $xpath->evaluate('normalize-space(Name)', $two)
    );
  }
);

var_dump($rows);

DOM没有访问子对象和值的神奇方法,可以使用Xpath获取它们。Xpath函数
string()
将第一个节点转换为字符串。如果节点列表为空,则返回空字符串
normalize-space()
做的更多。它用一个空格替换所有组的空白,并从字符串的开头和结尾将其剥离。

我建议使用DOM扩展,因为它更灵活:

$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
$doc->load('xml1.xml');

// Get the root node
$root = $doc->getElementsByTagName('FMPDSORESULT');
if (!$root->length)
  die('FMPDSORESULT node not found');
$root = $root[0];

// Pull the ROW tags from the document into an array.
$rows = [];
$nodes = $root->getElementsByTagName('ROW');
while ($row = $nodes->item(0)) {
  $rows []= $root->removeChild($row);
}

// Sort the array of ROW tags
usort($rows, function ($a, $b) {
  $a_name = $a->getElementsByTagName('Name');
  $b_name = $b->getElementsByTagName('Name');

  return ($a_name->length && $b_name->length) ?
    strcmp(trim($a_name[0]->textContent), trim($b_name[0]->textContent)) : 0;
});

// Append ROW tags back into the document
foreach ($rows as $row) {
  $root->appendChild($row);
}

// Output the result
echo $doc->saveXML();
输出

将行追加回文档中:

$root = $xpath->evaluate('/myns:FMPDSORESULT')[0];
foreach ($rows as $row) {
  $root->appendChild($row);
}

我建议使用DOM扩展,因为它更灵活:

$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
$doc->load('xml1.xml');

// Get the root node
$root = $doc->getElementsByTagName('FMPDSORESULT');
if (!$root->length)
  die('FMPDSORESULT node not found');
$root = $root[0];

// Pull the ROW tags from the document into an array.
$rows = [];
$nodes = $root->getElementsByTagName('ROW');
while ($row = $nodes->item(0)) {
  $rows []= $root->removeChild($row);
}

// Sort the array of ROW tags
usort($rows, function ($a, $b) {
  $a_name = $a->getElementsByTagName('Name');
  $b_name = $b->getElementsByTagName('Name');

  return ($a_name->length && $b_name->length) ?
    strcmp(trim($a_name[0]->textContent), trim($b_name[0]->textContent)) : 0;
});

// Append ROW tags back into the document
foreach ($rows as $row) {
  $root->appendChild($row);
}

// Output the result
echo $doc->saveXML();
输出

将行追加回文档中:

$root = $xpath->evaluate('/myns:FMPDSORESULT')[0];
foreach ($rows as $row) {
  $root->appendChild($row);
}

你说得对,DOM更加灵活和强大。但我建议在任何情况下都使用Xpath:-)@嗯,我喜欢XPath,但在这种特殊情况下,我认为它不会显著改进代码。你是对的,DOM更加灵活和强大。但我建议在任何情况下都使用Xpath:-)@我喜欢XPath,但在这种特殊情况下,我认为它不会显著改进代码。