从任何WSDL可靠地解析文档标记

时间:2018-11-26 14:28:58

标签: php xml soap wsdl simplexml

我需要解析XML文件,所以我总是找到元素apparently,该元素可以是许多其他元素的第一个子元素,因此没有简单的方法来解析它。目前,我仅从此WSDL进行解析。

<portType name="ndfdXMLPortType">
<operation name="NDFDgen">
<documentation>My Documentation... lorem ipsum dolor sit amet</documentation>
<input message="tns:NDFDgenRequest" />
<output message="tns:NDFDgenResponse" />
</operation>
</portType>

使用此代码

  $documentations = $styles = $outputs = array();
  if (!empty($array)) {
    foreach ($array['portType']['operation'] as $operation) {
      $documentations[$operation['@attributes']['name']] = $operation['documentation'];
    }
    foreach ($array['binding']['operation'] as $key => $operation) {
      $styles[$operation['@attributes']['name']] = $operation['operation']['@attributes']['style'];
      $outputs[$operation['@attributes']['name']] = $xml->binding->operation[$key]->output->body->asXML();
    }
  }

但是我需要从任何 WSDL文件中解析它。例如,在另一个WSDL中,它显示为。

<xs:sequence>
<xs:element name="BillingPeriod" type="ebl:BillingPeriodType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation> Installment Period.
<br />
<b>Optional</b>
<br />
</xs:documentation>
</xs:annotation>
</xs:element>

1 个答案:

答案 0 :(得分:2)

实际上,这看起来像两个不同的元素。第一个documentation将在WSDL名称空间(http://schemas.xmlsoap.org/wsdl/)中。您的第二个示例似乎是架构(http://www.w3.org/2001/XMLSchema)。

您的示例缺少名称空间定义。查找xmlnsxmlns:xs属性。以下3个示例都可以读为{http://schemas.xmlsoap.org/wsdl/}documentation

  • <documentation xmlns="http://schemas.xmlsoap.org/wsdl/"/>
  • <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>
  • <w:documentation xmlns:w="http://schemas.xmlsoap.org/wsdl/"/>

XML解析器将解析名称空间定义。您可以为节点使用相同的本地名称。根据前缀和名称空间定义,它们可能表示不同的内容。

您似乎在使用SimpleXML并将其转换为数组。不要进行这种转换。 SimpleXML允许您已经使用PHP语法访问XML。但是SimpleXMLElement对象仍然具有使访问更容易的方法。如果将其调试输出转换为数组,则将失去这些信息。

SimpleXMLElement允许您使用Xpath来获取节点:

$element = new SimpleXMLElement($xml);
// register your own prefixes for the namespaces
$element->registerXPathNamespace('xsd', 'http://www.w3.org/2001/XMLSchema');
$element->registerXpathNamespace('wsdl', 'http://schemas.xmlsoap.org/wsdl/');

// fetch the documentation elements from both namespaces
$expression = '//xsd:documentation|//wsdl:documentation';
var_dump(
    (string)$element->xpath($expression)[0]
);    

或在DOM中:

$document = new \DOMDocument();
$document->loadXML($xml);
$xpath = new \DOMXpath($document);
// register your own prefixes for the namespaces
$xpath->registerNamespace('xsd', 'http://www.w3.org/2001/XMLSchema');
$xpath->registerNamespace('wsdl', 'http://schemas.xmlsoap.org/wsdl/');

// fetch the documentation elements from both namespaces and 
// cast the first into a string
$expression = 'string(//xsd:documentation|//wsdl:documentation)';
var_dump(
    $xpath->evaluate($expression)
);