1

我有一个脚本可以读取 XML 标记并将其打印在我的页面上。有些项目是链接(没有 HTML 标签),所以我创建了一个向它添加 HTML 链接标签的函数。但是,链接呈现为字符串而不是 HTML。

我知道它是因为我使用了 createTextNode,所以我需要一些将它作为对象而不是字符串返回的东西。

这是我的代码

function get_feeds() {
    $feeds = array(
        array(
            'name' => 'Agenda',
            'url' => 'http://www.beleefdokkum.nl//pages/rss.aspx?type=agenda',
            'get' => array('title', 'description', 'link'),
            'scope' => array(1, 10)
        ),
        array(
            'name' => 'News',
            'url' => 'http://www.beleefdokkum.nl//pages/rss.aspx?type=nieuws',
            'get' => array('title', 'description', 'link'),
            'scope' => array(1, 10)
        ),
        array(
            'name' => 'Social media',
            'url' => 'http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=NOFriesland',
            'get' => array('description'),
            'scope' => array(1, 10)
        )
    );

    $result = new DOMDocument();

    function linkify($text) {
        $text = preg_replace('/(https?:\/\/\S+)/', '<a href="\1" class="preg-links">\1</a>', $text);
        $text = preg_replace('/(^|\s)@(\w+)/', '\1@<a href="http://twitter.com/\2" class="preg-links">\2</a>', $text);
        $text = preg_replace('/(^|\s)#(\w+)/', '\1#<a href="http://search.twitter.com/search?q=%23\2" class="preg-links">\2</a>', $text);
        return $text;
    }

    foreach ($feeds as $feed) {
        $xml = new DOMDocument();
        $xml->load($feed['url']);
        $frame = $result->createElement('div');
        $frame->setAttribute('class', 'feed_frame');
        $result->appendChild($frame);
        $name = $result->createElement('h1', $feed['name']);
        $name->setAttribute('class', 'feed_name');
        $frame->appendChild($name);
        $content = $result->createElement('div');
        $content->setAttribute('class', 'feed_content');
        $frame->appendChild($content);
        for ($i = $feed['scope'][0]; $i < $feed['scope'][1]; $i++) {
            $item = $result->createElement('span');
            $item->setAttribute('class', 'feed_item');
            $content->appendChild($item);
            foreach ($feed['get'] as $get) {
                $object = $result->createElement('p');
                $text = $result->createTextNode(linkify($xml->getElementsByTagName($get)->item($i)->nodeValue));
                $object->appendChild($text);
                $object->setAttribute('class', 'feed_'.$get);
                $item->appendChild($object);
            }
        }
    }
    return $result->saveHTML();
}
4

1 回答 1

0

可能还有其他方法,但我会通过在执行正则表达式匹配时创建文本节点和锚来解决它:

$node = $dom->createElement('p');
linkify($doc, $node, 'T1 @test T2 #test T3 http://www.stackoverflow.com T4');

linkify()函数采用现有节点并根据给定字符串创建文本节点和锚点。

function linkify($dom, $node, $text)
{
    // we combine all possible patterns in one expression
    $re = '/(https?:\/\/\S+)|(?:^|\s)@(\w+)|(?:^|\s)#(\w+)/';
    // we capture pattern offsets
    $flags = PREG_SET_ORDER | PREG_OFFSET_CAPTURE;

    $offset = 0;
    if (preg_match_all($re, $text, $matches, $flags)) {
        foreach ($matches as $match) {
            // set start and end markers of the matched pattern
            $start = $match[0][1];
            $end = $match[0][1] + strlen($match[0][0]);
            // process each pattern based on the resulting matches
            if (isset($match[3])) { // Twitter hash
                $start += 2; // skip space and #
                $url = 'http://search.twitter.com/search?q=' . 
                    urlencode("#{$match[3][0]}");
                $anchor = anchor($dom, $url, $match[3][0]);
            } elseif (isset($match[2])) { // Twitter user
                $start += 2;
                $url = 'http://twitter.com/' . urlencode($match[2][0]);
                $anchor = anchor($dom, $url, $match[2][0]);
            } else { // standard url
                $anchor = anchor($dom, $match[1][0], $match[1][0]);
            }

            if ($start > $offset) {
                // we have text in between previous match (or start) and here
                $str = substr($text, $offset, $start - $offset);
                $node->appendChild($dom->createTextNode($str));
            }
            // insert the new anchor
            $node->appendChild($anchor);
            // keep track of last match marker
            $offset = $end;
        }
        // add last text node
        $node->appendChild($dom->createTextNode(substr($text, $offset)));
    }
}

这将是您运行时的输出->saveHTML()

<p>
  T1 
   @<a href="http://twitter.com/datibbaW" class="preg-links">datibbaW</a> 
  T2
   #<a href="http://search.twitter.com/search?q=%23test" class="preg-links">test</a>
  T3 
   <a href="http://www.stackoverflow.com" class="preg-links">http://www.stackoverflow.com</a>
   T4</p>

我正在使用便利功能来创建锚点:

function anchor($dom, $url, $text)
{
    $anchor = $dom->createElement('a', $text);
    $anchor->setAttribute('href', $url);
    $anchor->setAttribute('class', 'preg-links');

    return $anchor;
}
于 2013-04-19T02:28:47.977 回答