Php 在一个元素中获取XML内容并将结果拆分为其他子元素
我使用的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元素
<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),但前两行和后两行是相同的。