php解析xml文档

时间:2016-03-24 01:22:41

标签: php xml simplexml simplexml-load-string

我一直在尝试解析这个xml文档,以便在过去的2个小时内循环“table”元素,但它无效!我已经尝试过这个主要作为参考,但它不起作用simplexml_load_string returns blank array

这是我的XML,我如何遍历'table'节点?

    <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><GetMovieListResult xmlns="http://vista.co.nz/services/WSVistaWebClient.DataTypes/1/"><Result>OK</Result><DatasetXML><NewDataSet>
      <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
        <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
          <xs:complexType>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
              <xs:element name="Table">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="Cinema_strID" type="xs:string" minOccurs="0" />
                    <xs:element name="Movie_strID" type="xs:string" minOccurs="0" />
                    <xs:element name="Movie_strName" type="xs:string" minOccurs="0" />
                    <xs:element name="Movie_strRating" type="xs:string" minOccurs="0" />
                    <xs:element name="Movie_strName_2" type="xs:string" minOccurs="0" />
                    <xs:element name="Movie_strRating_2" type="xs:string" minOccurs="0" />
                    <xs:element name="Movie_HOFilmCode" type="xs:string" minOccurs="0" />
                    <xs:element name="Movie_intFCode" type="xs:int" minOccurs="0" />
                    <xs:element name="CinOperator_strCode" type="xs:int" minOccurs="0" />
                    <xs:element name="CinOperator_strName" type="xs:int" minOccurs="0" />
                    <xs:element name="Event_strCode" type="xs:string" minOccurs="0" />
                    <xs:element name="Event_strFilmsIndependent" type="xs:string" minOccurs="0" />
                    <xs:element name="MemberMovie" type="xs:string" minOccurs="0" />
                    <xs:element name="HOPK" type="xs:string" minOccurs="0" />
                    <xs:element name="Movie_intList_Pos" type="xs:int" minOccurs="0" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:choice>
          </xs:complexType>
        </xs:element>
      </xs:schema>
      <Table>
        <Cinema_strID>0</Cinema_strID>
        <Movie_strID>0010000845</Movie_strID>
        <Movie_strName>BATMAN Vs SUPERMAN</Movie_strName>
        <Movie_strRating>PG13</Movie_strRating>
        <Movie_strName_2 />
        <Movie_strRating_2 />
        <Movie_HOFilmCode />
        <Movie_intFCode>0</Movie_intFCode>
        <Event_strCode />
        <MemberMovie>N</MemberMovie>
        <HOPK />
        <Movie_intList_Pos>50</Movie_intList_Pos>
      </Table>
      <Table>
        <Cinema_strID>0</Cinema_strID>
        <Movie_strID>0010000846</Movie_strID>
        <Movie_strName>BATMAN Vs SUPERMAN VIP</Movie_strName>
        <Movie_strRating>PG13</Movie_strRating>
        <Movie_strName_2 />
        <Movie_strRating_2 />
        <Movie_HOFilmCode />
        <Movie_intFCode>0</Movie_intFCode>
        <Event_strCode />
        <MemberMovie>N</MemberMovie>
        <HOPK />
        <Movie_intList_Pos>50</Movie_intList_Pos>
      </Table>

    </NewDataSet></DatasetXML></GetMovieListResult></soap:Body></soap:Envelope>

1 个答案:

答案 0 :(得分:1)

你可能在NameSpaceURIs上遇到了一些问题。

NamespaceURI的特征是带冒号(<soap:Envelope>)的标签和NamespaceURI声明,带有“xmlns:”前缀的属性(通常是根元素):

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" .... >
<!--           └──┬─┘└┬─┘  └────────────────────────┬──────────────┘
                  │   └──────┐                      │
   NameSpace Declaration   NameSpace Prefix   NameSpaceURI      -->

应用于没有前缀的标签的主NameSpaceURI由属性“xmlns”表征,没有逗号。

要搜索NameSpaceURI元素,您可以使用->children(),使用相对NameSpaceURI作为参数:

$children = $xml->children( 'http://schemas.xmlsoap.org/soap/envelope/' );

或添加可选参数 is_prefix _ ,NameSpaceURI前缀:

$children = $xml->children( 'soap', True );

在您的情况下,在访问<Table>之前,您必须选择直接父节点:

$xml = simplexml_load_file( $filePath );

$body               = $xml->children( 'soap', True );
$GetMovieListResult = $body->children();
$NewDataSet         = $GetMovieListResult->children()->DatasetXML->NewDataSet;
#                                                      └───────────────────┬┘
#                                         Here we can use standard syntax ─┘

此时,我们可以捕捉到所有电影名称:

$movieNames = array[];
foreach( $NewDataSet->Table as $table )
{
    $movieNames[] = (string) $table->Movie_strName;
}

现在有$movieNames数组:

Array
(
    [0] => BATMAN Vs SUPERMAN
    [1] => BATMAN Vs SUPERMAN VIP
)

通过此方法,您可以检索任何其他节点值。

使用XPath

更舒适的方法是使用XPath,这是一种使用路径表达式在XML文档中导航的语法。要在Namespaced XML中使用XPath,首先我们必须注册我们想要在模式中使用的命名空间:

$xml->registerXPathNamespace( 'xmlns', 'http://vista.co.nz/services/WSVistaWebClient.DataTypes/1/' );

在这种情况下,我已经注册了主要的NameSpaceURI 1 。然后我们可以搜索模式:

$tables = '//xmlns:Table';

模式开头的双斜杠表示:“搜索匹配以下模式的节点,无论它们在哪里” 2 。现在,我们有一组节点可以作为先例示例迭代:

foreach( $tables as $table )
{
    (...)

注意:

  1. 我们可以使用任何注册NameSpaces的字符组合,不一定是文档中使用的字符组合。即如果我以这种方式注册主NS:$xml->registerXPathNamespace( 'x', 'http://vista.co.nz/services/WSVistaWebClient.DataTypes/1/' );,那么我可以用这种方式构建XPath模式://x:Table

  2. 要搜索确切的降序树,我们可以使用/代替//。但是,在这种情况下,我们必须注册树中出现的所有NameSpace。