XML 2 文本问题中的数组标记

XML 2 Array Markup in Text Issue

我正在为以下问题而苦恼。我尝试将 xml 文档转换为 PHP 中的数组,到目前为止工作正常。但我确实有一些特殊元素,其中包含带有标记的文本。元素看起来像这样:

<section>
    <name>sectionname</name>
    <subsection>
        <subsectionname>one</subsectionname>
        <element>
            <text>some text <xref>a</xref>, <xref>b</xref>, <xref>c</xref></text>
        </element>
    </subsection>
    <subsection>
        <subsectionname>two</subsectionname>
        <element>
            <text>some text <xref>a</xref>, <xref>b</xref>, <xref>c</xref></text>
        </element>
    </subsection>
</section>

我首先尝试使用简单xml:

$xml = simplexml_load_string($string) or die("Error: Cannot create object");
$json = json_encode($xml);
$array = json_decode($json, TRUE);

但这将 return 包含 "some text , , and some more" 的元素,但没有外部参照的内容。我真正想要的是全文"some text a, b, c and some more",但恐怕我不知道如何实现。 我已经给了 DOMDocument 一个机会,但整个事情都遇到了问题,因为它非常复杂 xml.

有什么想法可以让我收到我想要的东西吗?

编辑:我添加了一个更复杂的 xml 示例。如您所见,我需要遍历各个部分,然后是子部分,然后在其中遍历带有标记和文本的元素。

使用起来非常简单 DOMDocument - 如果我理解正确的话你可以这样尝试 ~ 虽然只有一小段 XML 这可能有点离谱

<?php

    $strxml='<?xml version="1.0" encoding="UTF-8"?>
        <root>
            <element>
                <text>some text <xref>a</xref>, <xref>b</xref>, <xref>c</xref> and some more</text>
            </element>
            <element>
                <text>a banana <xref>FFF</xref>, <xref>GGG</xref>, <xref>ZZZ</xref> and some more bananas</text>
            </element>
        </root>';

    $dom=new DOMDocument;
    $dom->loadXML( $strxml );

    $col=$dom->getElementsByTagName('element');
    $output=array();

    foreach( $col as $node )$output[]=$node->childNodes[1]->nodeValue;


    printf('<pre>%s</pre>',print_r( $output, true ) );

?>

会输出

Array
(
    [0] => some text a, b, c and some more
    [1] => a banana FFF, GGG, ZZZ and some more bananas
)

SimpleXML 的问题在于它倾向于将文本节点分组为 1 个块。为了能够获得正确拆分的文本,您往往必须使用 DOMDocument。

如您所见,这将加载文档,然后使用 XPath 查找 Element/Text 节点(这只是为了找到正确的点 - 如果您愿意,可以使用 getElementsByTagName())。然后在该节点内,它再次使用 XPath 查找所有文本节点(使用 descendant::text()),然后从文档中的 <text> 节点按顺序获取每段文本。

对于每个文本节点,这会创建一个空白 $text 字符串并在循环中向其添加内容,然后显示它...

$data = '<section>
    <name>sectionname</name>
    <subsection>
        <subsectionname>one</subsectionname>
        <element>
            <text>some text <xref>a</xref>, <xref>b</xref>, <xref>c</xref></text>
        </element>
    </subsection>
    <subsection>
        <subsectionname>two</subsectionname>
        <element>
            <text>some text <xref>a</xref>, <xref>b</xref>, <xref>c</xref>d</text>
        </element>
    </subsection>
</section>';

$dom = new DOMDocument();
$dom->loadXML($data);
$xp = new DOMXPath($dom);
foreach ( $xp->query("//element/text") as $element ) {
    $text = '';
    foreach ( $xp->query("descendant::text()", $element) as $textNode )    {
        $text .= $textNode->textContent;
    }   
    echo $text.PHP_EOL;
}

这个显示(我修改了第二个帮助)...

some text a, b, c
some text a, b, cd

编辑:

正如 ThW 指出的那样,使用 textContent 将获取包括子节点在内的所有文本,因此您可以将内部循环缩短为

foreach ( $xp->query("//element/text") as $element ) {
    echo $element->textContent.PHP_EOL;
}