代码之家  ›  专栏  ›  技术社区  ›  Norgul

如何控制xmpp xml

  •  0
  • Norgul  · 技术社区  · 6 年前

    我正在做一个 XMPP PHP client 目前,在测试阶段,我已经使Stanzas(即存在)如下:

        const PRESENCE = <<<PRESENCE
    <presence from="{from}" to="{to}" type="{type}" />
    PRESENCE;
    
        const PRIORITY = <<<PRIORITY
    <presence from="{from}">
        <priority>{priority}</priority>
    </presence>
    PRIORITY;
    

    然而,在开发一个库时,我想做一些编程,因为我觉得这种方法看起来像是硬编码的,即使我确实像这样解析它,例如:

    $preparedString = str_replace(
        ['{from}', '{priority}'],
        [$from, $priority],
        Xml::PRIORITY
    );
    

    所以我最终创造了一个 Presence 类,该类应包含所有与状态相关的方法,并充当某种XML生成器,它如下所示:

    private $instance = null;
    
    public function __construct()
    {
        $this->instance = new \DOMDocument();
        $this->instance->formatOutput = true;
    }
    
    public function requestPresence(string $from, string $to, string $type = "subscribe")
    {
        $presenceNode = $this->instance->createElement('presence');
        $presenceNode->setAttribute("from", $from);
        $presenceNode->setAttribute("to", $to);
        $presenceNode->setAttribute("type", $type);
    
        return $this->instance->saveXML($presenceNode);
    }
    
    public function setPriority(int $priority, string $from = null)
    {
        $presenceNode = $this->instance->createElement('presence');
        if ($from)
            $presenceNode->setAttribute("from", $from);
    
        $priorityNode = $this->instance->createElement('priority');
        $priorityNode->appendChild($this->instance->createTextNode($priority));
    
        $presenceNode->appendChild($priorityNode);
    
        return $this->instance->saveXML($presenceNode);
    }
    

    但现在我有了一些疑问,因为我已经将代码翻了三倍,而且它以前的可读性更高。我希望它简单有效,没有代码重复,但我觉得这里缺少了一些东西。有更巧妙的方法吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Nigel Ren    6 年前

    DOMDocument是一个更详细的XML接口,您可以使用simpleXML,这将减少锅炉板代码。

    class XML {
        public static function requestPresence(string $from, string $to, string $type = "subscribe")
        {
            $instance = new SimpleXMLElement("<presence />");
            $instance["from"] = $from;
            $instance["to"] = $to;
            $instance["type"] = $type;
    
            return $instance->asXML();
        }
    
        public static function setPriority(int $priority, string $from = null)
        {
            $instance = new SimpleXMLElement("<presence />");
            if ($from)  {
                $instance["from"] = $from;
            }
            $instance->priority = $priority;
    
            return $instance->asXML();
        }
    }
    

    这假设它们是两个独立的需求,它们只是实用功能,而不必维护任何状态。

    如果需要使用更多选项构建文档,则以下内容可能更有用…

    class XML2 {
        private $instance = null;
    
        public function __construct()   {
            $this->instance = new SimpleXMLElement("<presence />");
        }
    
        public function requestPresence(string $from, string $to, string $type = "subscribe")
        {
            $this->instance["from"] = $from;
            $this->instance["to"] = $to;
            $this->instance["type"] = $type;
    
            return $this;
        }
    
        public function setPriority(int $priority, string $from = null)
        {
            if ($from)  {
                $this->instance["from"] = $from;
            }
            $this->instance->priority = $priority;
    
            return $this;
        }
    
        public function getXML()    {
            return $this->instance->asXML();
        }
    }
    

    用…

    echo  (new XML2())->requestPresence("from", "to", "type")
        ->setPriority(1)
        ->getXML();
    

    创造…

    <?xml version="1.0"?>
    <presence from="from" to="to" type="type"><priority>1</priority></presence>
    

    使用domdocument或simplexml解决方案会比您的原始版本感觉更膨胀,但会提供一个比依赖字符串处理更可维护的更健壮的解决方案。