【问题标题】:php xml parse inline nodes inlinephp xml解析内联节点内联
【发布时间】:2015-03-22 16:04:29
【问题描述】:

我有一个 xml 文档,其中包含与文本混合的节点。我想将此节点解析为与现有文本一致的粗体文本。我已经在网上搜索和研究了答案,但找不到解决方法。我的 xml 文件如下所示:

<song>
  <lyrics>
    <verse name="v1">
      <lines>
        On a <chord name="A"/>hill far away stood an <chord name="D"/>old rugged cross, The <chord name="E7"/>emblem of suff'ring and <chord name="A"/>shame;<br/>
        And I <chord name="A"/>love that old cross where the <chord name="D"/>dearest and best, For a <chord name="E7"/>world of lost sinners was <chord name="A"/>slain.
      </lines>
    </verse>
  </lyrics>
</song>

解析我所做的诗句的文本:

$xml = @simplexml_load_file($file) or die("Can't read XML-SONG file...");
$myVerse= $xml->lyrics->verse[0]->lines;
echo $myVerse;

打印:

在远处的山丘上矗立着一个古老而崎岖的十字架, 苦难和耻辱的象征;我爱那个古老的十字架,最亲爱的和最好的,因为一个迷失的罪人的世界被杀了。

但是如何将那些 解析为文本之间的(粗体)文本?..

【问题讨论】:

  • 您能否举例说明输出的实际应该是什么样子?
  • 如果我能这样做就好了:在远处的 (A) 山上矗立着 (D) 古老的崎岖十字架

标签: php xml


【解决方案1】:
$xml = @simplexml_load_file($file) or die("Can't read XML-SONG file...");
$myVerse= $xml->lyrics->verse[0]->lines;

$regex='/(<chord name="(.{1,2})"\/>)/';
$replacement = '<B>$2</B> ';
$myVerse= preg_replace($regex,$replacement,$myVerse);
echo $myVerse;

这将输出

在远处的A山丘上,矗立着一个D古老的崎岖十字架,E7象征着苦难和A 羞耻;

您可以修改替换字符串以满足显示和弦的需要。

【讨论】:

  • 我尝试替换,但这似乎不起作用,因为当你 'print_r' $myVerse 时,它​​只显示数组详细信息,但当我回显 $myVerse 时,它​​只打印纯文本没有 节点
  • 编辑了我的答案以包括您的开头行。这将在 的位置输出加粗的和弦字母。
  • 我试过了,但是不行。我不知道为什么,但是当我回显 $myVerse 时,它​​根本不显示 节点,但是当我 print_r($myVerse) 时,它向我显示了一个像这样的复杂数组: SimpleXMLElement Object ( [chord] =>数组([0] => SimpleXMLElement 对象([@attributes] => 数组([名称] => A))[1] => SimpleXMLElement 对象([@attributes] => 数组([名称] => D)) [2] => SimpleXMLElement 对象 ([@attributes] => 数组 ([name] => E7)) [3] => Sim...
【解决方案2】:

好的,为什么和弦节点在打印为 echo $myVerse 时没有显示(即使在节点应该能够显示的页面源中)是因为我忘记输出我的 $myVerse asXML()。因此变量应该这样改变:

$xml = @simplexml_load_file($file) or die("Can't read XML-SONG file...");
$myVerse= $xml->lyrics->verse[0]->lines;->asXML();

当我们在页面中打印这个时,我们可以在页面源中看到节点

echo $myVerse;

只有这样我们才能按照@greg_diesel 建议的方式替换节点:

$regex='/(<chord name="(.{1,2})"\/>)/';
$replacement = '<B>$2</B> ';
$myVerse= preg_replace($regex,$replacement,$myVerse);
echo $myVerse;

感谢@greg_diesel,但答案在 ->asXML() 这项研究帮助我更好地学习了 xml,希望这对其他人也有帮助!

【讨论】:

    【解决方案3】:

    simplexml_load_file 根本没有传递您的和弦标签。我在第一篇文章中做了这个假设。 负载产生的实际 XML 是

    SimpleXMLElement Object
    (
        [lyrics] => SimpleXMLElement Object
            (
                [verse] => SimpleXMLElement Object
                    (
                        [@attributes] => Array
                            (
                                [name] => v1
                            )
    
                        [lines] => 
            On a hill far away stood an old rugged cross, The emblem of suff'ring and shame;
            And I love that old cross where the dearest and best, For a world of lost sinners was slain
                    )
            )
    )
    

    所以我转而使用 DOM,但由于 chord 标签无效,它们仍然被删除。我在这个线程PHP DOM get nodevalue html? (without stripping tags)找到了一些帮助

    我就这样结束了。哪个做你想要的。

    <?php
    
    function get_inner_html( $node ) { 
        $innerHTML= ''; 
        $children = $node->childNodes; 
        foreach ($children as $child) { 
            $innerHTML .= $child->ownerDocument->saveXML( $child ); 
        } 
    
        return $innerHTML;  
    } 
    
    $file='myxmlfile.xml';
    $doc = new DOMDocument();
    $doc->load($file);
    $lines=$doc->getElementsByTagName('lines');
    $linesarray=array();
    foreach ($lines as $node) {
      $linesarray[]=get_inner_html($node);
    }
    
    foreach($linesarray as $myVerse){
        $regex='/(<chord name="(.{1,2})"\/>)/';
        $replacement = '<B>$2</B> ';
        $myVerse= preg_replace($regex,$replacement,$myVerse);
        echo $myVerse;
    }
    
    ?>
    

    这给出了结果

    在远处的A山上矗立着一个D古老的崎岖十字架,E7象征着痛苦和A 耻辱;
    A爱那个古老的十字架,D在那里最亲爱和最好的,因为E7迷失罪人的世界是A 被杀。

    【讨论】:

    • 您的方法有效,因此我将授予您正确答案的好处,但是,我最终将使用我的 ->asXML() 答案,因为它需要更少的代码.我相信你的方法在技术上是正确的;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-19
    • 1970-01-01
    • 2020-01-07
    相关资源
    最近更新 更多