如何在发送到 Web 服务之前清理 xml 请求


How to clean xml request before sending to web service

美好的一天,我正在尝试将 xml 发送到 Web 服务,但在发送之前需要清理 XML。到目前为止,我已经尝试了不同的方法,现在被困了一段时间。

我从表单中捕获数据并将其发布到我的 php 文件进行处理。如果用户没有在长度/宽度/高度中输入任何数据,那么我想清理我的 xml 并删除空元素,以便它可以在发送 xml 请求的服务器上通过验证。

下面是从我的帖子中获取的数据片段,并相应地构建 xml 文件,但如果省略维度怎么办?我还可以清理其他空元素吗?

$xmlRequest = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<mailing-scenario xmlns="http://www.mysite.com/ws/ship/rate-v2">
<customer-number>{$mailedBy}</customer-number>
  <parcel-characteristics>
    <weight>{$weight}</weight>
      <dimensions>
        <length>{$length}</length>
        <width>{$width}</width>
        <height>{$height}</height>
      </dimensions>
  </parcel-characteristics>
<origin-postal-code>{$originPostalCode}</origin-postal-code>
<destination>
<domestic>
 <postal-code>{$postalCode}</postal-code>
</domestic>
</destination>
</mailing-scenario>
XML;

$xmlRequest = phpquery::newDocument(); 
$xp = new DOMXPath($xmlRequest->getDOMDocument());
foreach($xp->query('//*[not(node()) or normalize-space() = ""]') as $node) {
$node->parentNode->removeChild($node);
} 
好的,

这里有一个简单的 dom 的例子。也许首先要注意几点,如果没有给出客户编号或负权重,您将决定该怎么做,......
因此,您必须清理XML,但有时清理它会使请求无效,或者用户可能会得到一些他意想不到的结果。例如,他可能会把1kg作为重量,你去掉kg,因为重量是g设置的,而那里的绳子是错误的。如果你不告诉用户,他可能会对你大喊大叫!
而且仅仅因为所有节点都有效并不意味着请求是正确的,因为可能缺少一些节点,因此您还必须检查要求!

关于效率的最后一句话,如果你可以在没有XML的情况下从用户那里获得所有这些字段,因为用户一次只发送一个包裹。这样做,只需检查该数据是否正确即可。
如果你必须使用XML,仍然一次只发送一个包,你可以获取数据检查有效性并重建经过验证的XML。

如果我知道这些 XML 请求可能非常广泛和/或格式复杂,我会使用此示例。

function cleanXML($data){
    // ok the data is string! So get your node.
    $node = simplexml_load_string($data);
    // now we can iterate throught all child nodes:
    foreach($node->children() as $child){
        //so here we got the childrens
        // All child nodes of the root should be mailing scenarios
        if($child->getName() == "mailing-scenario"){
            //otherwise we check if mailing scenario is valid
            if(!validateMScenario($child)){
                //This node seems not so valid
                //you have to decide what to do now!
            }
        }
        else{
            //Here we remove all nodes that are different
            unset($child[0]);
            echo "Error: Needed to remove Node";
        }
    }
    // Just give them their cleaned XML!
    return $node->asXML();
}

function validateMScenario($ms){
    // These var's safe if the requirements are fullfilled
    $is_customer_number_set = 0
    $is_weight_set = 0
    $is_package_set = 0
    // Again iterate over nodes
    foreach($ms->children as $child){
        //check for customer number
        if($child->getName() == "customerNumber"){
            if($is_customer_number_set == 1){
                echo "You just need one customer number I guess?!"
                return -1
            }
            value = (string) $child;
            // Check if customer number is existing
            if(strlen(value) == 0 || !is_int(value) || intval(value) == -1){
                echo "Dude you need a number!";
                return -1
            }
            $is_customer_number_set = 0;
        }
        else if($node->getName() == "parcel-characteristics"){
             //Ok I hope it should be pretty clear what to do here!
             //...
        }
        else{
             //Remove node again?
        }
    }
    // All requirements fullfilled?
    return ($is_customer_number_set && $is_weight_set && $is_package_set);
}