Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.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 在一个元素中获取XML内容并将结果拆分为其他子元素_Php_Xml - Fatal编程技术网

Php 在一个元素中获取XML内容并将结果拆分为其他子元素

Php 在一个元素中获取XML内容并将结果拆分为其他子元素,php,xml,Php,Xml,我使用的xml文件如下所示: <text> <paragraph/> First text <paragraph/> Second text </text> <text> <paragraph/> Third text <paragraph/> Fourth text </text> 第一个文本 第二文本 第三文本 第四文本 我需要得到text元素

我使用的xml文件如下所示:

<text>
  <paragraph/>
    First text
  <paragraph/>
    Second text
</text>
<text>
  <paragraph/>
    Third text
  <paragraph/>
    Fourth text
</text>

第一个文本
第二文本
第三文本
第四文本
我需要得到text元素的值,但结果应该是4行。因此,每个
元素都会开始新行:

1 |第一个文本
2 |第二个文本
3 |第三个文本
4 |第四个文本

我的代码:

$filexml = File::get('../file.xml');

$xml = simplexml_load_string($filexml);

for ($i=1; $i < count($xml->text) + 1; $i++) {

    foreach ($xml->text as $text_item) {
        echo $i++." | ".$text_item."<br/>";
    }

}
$filexml=File::get('../File.xml');
$xml=simplexml\u load\u字符串($filexml);
对于($i=1;$itext)+1;$i++){
foreach($xml->text as$text\u项){
echo$i++.“|”。$text_项。“
”; } }
我的结果是:

1 |第一个文本第二个文本
2 |第三文本第四文本

接下来我该怎么办?或者可能有不同的方法如何达到预期的结果?

尝试改变这一点:

<text>
  <paragraph/>
    First text
  <paragraph/>
    Second text
</text>
<text>
  <paragraph/>
    Third text
  <paragraph/>
    Fourth text
</text>

第一个文本
第二文本
第三文本
第四文本
为此:

<text>
  <paragraph/>
    First text
  <paragraph/>
</text>
<text>
  <paragraph/>
    Two text
  <paragraph/>
</text>
<text>
  <paragraph/>
    Three text
  <paragraph/>
</text>
<text>
  <paragraph/>
    Four text
  <paragraph/>
</text>

第一个文本
两个文本
三个文本
四个文本

好的,这并不特别漂亮,我建议您仍然可以尝试使用XPath,但现在

<?php

$filexml = "<root>
<text>
<paragraph/>
First text
<paragraph/>
Second text
</text>
<text>
<paragraph/>
Third text
<paragraph/>
Fourth text
</text>
</root>";

$xml = simplexml_load_string($filexml);
$i=1;

foreach($xml->text as $textNode)
{
    $textCounter = 1;
    foreach ($textNode->paragraph as $text_item) {
        echo $i++." | ".trim(explode(PHP_EOL.PHP_EOL, (string)$textNode)[$textCounter++])."<br/>";
    }
}


?>
文本作为$textNode)
{
$textCounter=1;
foreach($textNode->段落作为$text\u项){
echo$i++.“|”。.trim(explode(PHP_EOL.PHP_EOL,(string)$textNode)[$textCounter++])。“
”; } } ?>
您基本上走在正确的轨道上,但是您的内部循环需要迭代
段落
节点,而不是再次迭代
文本
节点。然后,您还需要能够在
text
节点中拆分文本。如果文件的每一行都有内容,那么您就可以了,因为您可以在换行符上拆分。如果它不能(所有内容都在一行上),那么这将不起作用。

您可以使用和。在表达式中,可以使用获取文本节点

然后您可以循环这些内容并检查空字符串

$filexml = File::get('../file.xml');
$doc = new DOMDocument();
$doc->loadXML($filexml);
$xpath = new DOMXpath($doc);
$i = 1;
$expression = "//text/text()";
foreach ($xpath->query($expression) as $text) {
    $result = trim($text->nodeValue);
    if ($result !== "") {
        echo sprintf("%d | %s<br>", $i++, $result);
    }
}
$filexml=File::get('../File.xml');
$doc=新的DOMDocument();
$doc->loadXML($filexml);
$xpath=新的DOMXpath($doc);
$i=1;
$expression=“//text/text()”;
foreach($xpath->query($expression)作为$text){
$result=trim($text->nodeValue);
如果($result!==“”){
echo sprintf(“%d |%s
”,$i++,$result); } }

SimpleXML不能很好地处理混合子节点。为此,您需要使用DOM。可以使用Xpath表达式获取节点(文本也是节点)

//text/*|//text/text()[规范化空格(.)!=“”]
筛选
文本中的任何子元素节点或任何文本节点(包括cdata节)。它将忽略只包含空格的文本节点

结果是可以使用foreach迭代的节点列表。检查它是否是分隔符(一个
段落
元素节点)。如果是,则输出缓冲区,否则将节点的文本内容添加到缓冲区

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);

$buffer = '';
$counter = 0;
foreach ($xpath->evaluate('//text/*|//text/text()[normalize-space(.) != ""]') as $node) {
  if ($node instanceof DOMElement && $node->localName === 'paragraph') {
    if ($buffer !== '') {
      echo ++$counter, ' | ', trim($buffer), "\n";
      $buffer = '';
    }
  } else {
    $buffer .= $node->textContent;
  }
}
if ($buffer !== '') {
  echo ++$counter, ' | ', trim($buffer), "\n";
}
输出:

1 | First text
2 | Second text
3 | Third text
4 | Fourth text

我有大约70个包含数千行的文件。我不想这样做……我不认为使用SimpleXML可以得到这样的结果。也许是XPath。问题在于,文本实际上不在
段落
元素/节点中。因此,访问它的唯一方法是在
文本
节点级别,在该级别上,第一个和第二个文本,然后是第三个和第四个文本。我已经使用它获得了4行输出(使用SimpleXML),但前两行和后两行是相同的。