可靠地解析来自任何 WSDL 的文档标签

Reliably parse documentation tag from any WSDL

我需要解析一个 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>

实际上,这看起来像是两个不同的元素。第一个 documentation 将在 WSDL 名称空间 (http://schemas.xmlsoap.org/wsdl/) 中。你的第二个例子,似乎是 schema(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 对象仍然具有使访问更容易的方法。如果将其调试输出转换为数组,则会丢失该信息和信息。

简单XML元素允许您使用 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)
);