Plesk XML 格式化

Plesk XML formatting

在 PHP 中,我有此代码用于为 plesk API.

制作 XML header
$request = <<<EOF
<packet version="1.6.7.0">
<mail>
<update>
   <set>
      <filter>
         <site-id>$site_id</site-id>
         <mailname>
            <name>$name</name>
            <autoresponder>
               <enabled>true</enabled>
               <subject>$subject</subject>
               <text>$mail_body</text>
               <end_date>$date</end_date>
            </autoresponder>
         </mailname>
      </filter>
   </set>
</update>
</mail>
</packet>
EOF;

但是我得到了这个响应:1014 解析器错误:无法从指定的源解析 XML

我已将 xml 放入 2、3、4 和制表符间距的格式中,但它似乎无法解析它。

我做错了什么?

你无法猜测通过字符串连接创建一个有效的 XML,尤其是当你有像电子邮件文本这样的复杂内容时。

XML 标签内不允许所有字符:您必须正确转义 not-allowed 个字符。幸运的是,php 有一些解析器可以为您完成这项工作。

首先,创建一个空的 XML 模板(使用 XML validator 检查其有效性):

$xml = '<?xml version="1.0" encoding="utf-8" ?>
<packet version="1.6.7.0">
<mail>
<update>
    <set>
        <filter>
            <site-id/>
            <mailname>
                <name/>
                <autoresponder>
                    <enabled/>
                    <subject/>
                    <text/>
                    <end_date/>
                </autoresponder>
            </mailname>
        </filter>
    </set>
</update>
</mail>
</packet>
';

然后,将其加载到 DOMDocument object 并初始化 DOMXPath object:

$dom = new DomDocument();
$dom->loadXML( $xml );
$xpath = new DOMXPath( $dom );

然后,找到您要更改的每个节点和 set/update 其节点值:

$nodes = $xpath->query( 'mail/update/set/filter/site-id' );
$nodes->item(0)->nodeValue = $site_id;

$nodes = $xpath->query( 'mail/update/set/filter/mailname/name' );
$nodes->item(0)->nodeValue = $name;

对于 <autoresponder> children,您可以对每个 child 执行循环,在搜索模式末尾使用 *

$nodes = $xpath->query( 'mail/update/set/filter/mailname/autoresponder/*' );
foreach( $nodes as $node )
{
    if( 'enabled' == $node->nodeName )
    {
        $node->nodeValue = 'true';
    }
    elseif( 'subject' == $node->nodeName )
    {
        $node->nodeValue = $subject;
    }
    elseif( 'text' == $node->nodeName )
    {
        $cdata = $dom->createCDATASection( $mail_body );
        $node->appendChild( $cdata );
    }
    elseif( 'end_date' == $node->nodeName )
    {
        $node->nodeValue = $date;
    }
}

注意邮件正文采用的不同语法:我在这里使用 CDATA 节点:如果您的 XML 不允许 CDATA,请将其替换为标准 ->nodeValue ] 句法。或者——相反——你必须对所有节点使用 CDATA 方法。

当 XML 准备就绪时,您可以通过以下方式回显它:

echo $dom->saveXML();

DOMXPath 允许在 XML 树中执行复杂的搜索:在您的情况下这不是强制性的,因为您从一个简短的、空的、明确的模板开始。我将它用于演示目的,但您可以像这样替换一行:

$nodes = $xpath->query( 'mail/update/set/filter/site-id' );

与:

$nodes = $dom->getElementsByTagName( 'site-id' );

它将正常工作。