PHP使用嵌套节点XML获取节点值

时间:2019-07-03 15:53:24

标签: php xml xpath

我有一个xml文件:

<Epo>
<Doc upd="add">
<Fld name="IC"><Prg><Sen>A01B1/00 <Cmt>(1585, 779)</Cmt></Sen></Prg></Fld>
<Fld name="CC"><Prg><Sen>A01B1/00 <Cmt>(420, 54%)</Cmt>;</Sen><Sen>B25G1/102 <Cmt>(60, 8%)</Cmt>;</Sen><Sen>A01B1/02 <Cmt>(47, 6%)</Cmt></Sen></Prg></Fld></Doc>
<Doc upd="add">
<Fld name="IC"><Prg><Sen>A01B1/02 <Cmt>(3847, 1718)</Cmt></Sen></Prg></Fld>
<Fld name="CC"><Prg><Sen>A01B1/02 <Cmt>(708, 41%)</Cmt>;</Sen><Sen>A01B1/022 <Cmt>(347, 20%)</Cmt>;</Sen><Sen>A01B1/028 <Cmt>(224, 13%)</Cmt></Sen></Prg></Fld></Doc>
</Epo>

我想获取节点值,例如:A01B1 / 00(1585,779)-A01B1 / 00(420,54%); B25G1 / 102(60,8%); A01B1 / 02(47,6%) 然后将它们格式化为表格的列。我怎样才能做到这一点? 我的代码:

<?php
    $doc = new DOMDocument;
    $doc->preserveWhiteSpace = false;
    $doc->load('test.xml'); //IPCCPC-epoxif-201905
    $xpath = new DOMXPath($doc);
    $titles = $xpath->query('//Doc/Fld'); 
        foreach ($titles as $title){
            echo $title->nodeValue ."<hr>";
            }
?>

我无法分离evrey节点。请帮助我。

1 个答案:

答案 0 :(得分:0)

我试图将其拆分以获取所有不同级别的内容,但是我认为主要问题是获取当前节点文本而没有子元素文本内容。 nodeValue使用DOMDocument,与textContent相同(根据手册)...

  

textContent此节点及其后代的文本内容。

在仅访问相对简单的层次结构时,使用DOMDocument并不是最容易使用的方法,并且要求您不断地对getElementsByTagName()进行调用(在这种情况下)以获取包含的元素,以下资源显示了如何使用此方法获取文档的每个部分...

foreach ( $doc->getElementsByTagName("Doc") as $item )    {
    echo "upd=".$item->getAttribute("upd").PHP_EOL;
    foreach ( $item->getElementsByTagName("Fld") as $fld )  {
        echo "name=".$fld->getAttribute("name").PHP_EOL;
        foreach ( $fld->getElementsByTagName("Sen") as $sen )  {
            echo trim($sen->firstChild->nodeValue) ." cmt = ".
                $sen->getElementsByTagName("Cmt")[0]->firstChild->nodeValue.PHP_EOL;
        }
    }
} 

但是,使用SimpleXML API可以提供更简单的解决方案。层次结构的每个级别都使用对象表示法进行访问,因此->Doc用于访问根节点之外的Doc元素,而foreach()循环则可以解决该问题。您还可以看到,仅使用元素名称($sen->Cmt)只会给您该节点的文本内容,而不是后代的内容(尽管您必须将其转换为字符串以从对象中获取其值)。 ..

$doc = simplexml_load_file("test.xml");

foreach ( $doc->Doc as $docElemnt )    {
    echo "upd=".(string)$docElemnt['upd'].PHP_EOL;
    foreach ( $docElemnt->Fld as $fld )    {
        echo "name=".(string)$fld['name'].PHP_EOL;
        foreach ( $fld->Prg->Sen as $sen )    {
            echo trim((string)$sen)."=".trim((string)$sen->Cmt).PHP_EOL;
        }
    }
}