我无法在 PHP 中读取和解析 XML 文件



我有一个xml文件,我试图访问xml文件中的数据,但它返回一个空数组。

我有一个xml文件,我试图访问xml文件中的数据,但它返回一个空数组。

问题是否出在文件本身?

我已经尝试使用基本的SimpleXML用法这是我使用的PHP代码:

<?php
libxml_use_internal_errors(TRUE);
$xml = file_get_contents("https://egytech4uu.herokuapp.com/data.xml");
$XML = simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA);
$json = json_encode($XML);
$arr = json_decode($json,TRUE);
print_r($arr);
?>
<?xml version="1.0" encoding="UTF-8"?>
<DataSet xmlns="http://tempuri.org/Prices_Feed/Service1">
<xs:schema id="Ticker" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="Ticker" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Time">
<xs:complexType>
<xs:sequence>
<xs:element name="TIME" type="xs:dateTime" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Ticker">
<xs:complexType>
<xs:sequence>
<xs:element name="SYMBOL" type="xs:string" minOccurs="0"/>
<xs:element name="ARABIC_NAME" type="xs:string" minOccurs="0"/>
<xs:element name="CLOSE" type="xs:decimal" minOccurs="0"/>
<xs:element name="OPEN" type="xs:decimal" minOccurs="0"/>
<xs:element name="ENGLISH_NAME" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<Ticker xmlns="">
<Time diffgr:id="Time1" msdata:rowOrder="0">
<TIME>2022-03-28T14:29:56+02:00</TIME>
</Time>
<Ticker diffgr:id="Ticker1" msdata:rowOrder="0">
<SYMBOL>OFH.CA</SYMBOL>
<ARABIC_NAME>اوراسكوم المالية القابضة</ARABIC_NAME>
<CLOSE>0.1820</CLOSE>
<OPEN>0.19</OPEN>
<ENGLISH_NAME>Orascom Financial Holding</ENGLISH_NAME>
</Ticker>
<Ticker diffgr:id="Ticker2" msdata:rowOrder="1">
<SYMBOL>AMOC.CA</SYMBOL>
<ARABIC_NAME>الاسكندرية للزيوت المعدنية</ARABIC_NAME>
<CLOSE>4.08</CLOSE>
<OPEN>4.33</OPEN>
<ENGLISH_NAME>Alexandria Mineral Oils Company</ENGLISH_NAME>
</Ticker>
<Ticker diffgr:id="Ticker3" msdata:rowOrder="2">
<SYMBOL>OIH.CA</SYMBOL>
<ARABIC_NAME>اوراسكوم للاستثمار القابضة</ARABIC_NAME>
<CLOSE>0.2250</CLOSE>
<OPEN>0.2280</OPEN>
<ENGLISH_NAME>Orascom Investment Holding</ENGLISH_NAME>
</Ticker>
<Ticker diffgr:id="Ticker4" msdata:rowOrder="3">
<SYMBOL>EDBM.CA</SYMBOL>
<ARABIC_NAME>المصرية لتطوير صناعة البناء (ليفت سلاب مصر )</ARABIC_NAME>
<CLOSE>0.2690</CLOSE>
<OPEN>0.2780</OPEN>
<ENGLISH_NAME>Egyptian for Developing Building Materials</ENGLISH_NAME>
</Ticker>
<Ticker diffgr:id="Ticker5" msdata:rowOrder="4">
<SYMBOL>MTIE.CA</SYMBOL>
<ARABIC_NAME>ام.ام جروب للصناعة والتجارة العالمية</ARABIC_NAME>
<CLOSE>4.13</CLOSE>
<OPEN>4.46</OPEN>
<ENGLISH_NAME>MM Group For Industry And International Trade</ENGLISH_NAME>
</Ticker>
<Ticker diffgr:id="Ticker6" msdata:rowOrder="5">
<SYMBOL>UNIP.CA</SYMBOL>
<ARABIC_NAME>يونيفرسال لصناعة مواد التعبئة و التغليف و الورق - يونيباك</ARABIC_NAME>
<CLOSE>0.4280</CLOSE>
<OPEN>0.4210</OPEN>
<ENGLISH_NAME>Universal For Paper and Packaging Materials (Unipack</ENGLISH_NAME>
</Ticker>
</Ticker>
</diffgr:diffgram>
</DataSet>

考虑SimpleXML的一种方法是,它不创建包含所解析的XML的对象,它只是为访问XML中的数据提供了一个API。因此,要使用它,您需要了解XML的结构,并决定要从中获取哪些数据。

在本例中,xmlns属性表示XML名称空间参考-如何在SimpleXML中处理名称空间(名称中带有冒号的标签和属性)?

您实际上并没有说明要输出什么数据,因此我将使用从Ticker元素的内部列表中获取SYMBOLS作为示例。要获得这些,您需要遍历:

  • <diffgr:diffgram>元素,在命名空间urn:schemas-microsoft-com:xml-diffgram-v1中,由其xmlns:diffgr属性表示
  • 外部<Ticker>元素,它位于一个空URI (xmlns="")的命名空间
  • <Ticker>元素,我们要循环
  • <SYMBOL>元素在每一个我们想要提取的字符串内容
$sx = simplexml_load_string($xml); // Note: no additional options needed here
// Switch to the namespace given by xmlns:diffgr=""...", and select the "diffgram" element
$diffgram = $sx->children('urn:schemas-microsoft-com:xml-diffgram-v1')->diffgram;
// Switch to the namespace with an empty URI, because the elements have xmlns=""
$emptyNamespaceChildren = $diffgram->children("");
// Select the outer Ticker element
$outerTicker = $emptyNamespaceChildren->Ticker;
// Loop over the inner Ticker elements
$symbols = [];
foreach ( $outerTicker->Ticker as $ticker ) {
// Get some data out, in this case the SYMBOL of each Ticker
// Using (string) gives us the content of the element, rather than an object
$symbols[] = (string)$ticker->SYMBOL;
}

注意,这里所有额外的变量只是为了可读性,在实践中您可能不会写得这么冗长。在另一种极端情况下,您可以将它们全部放在一行,遍历所有级别,直到您想要循环的部分,像这样:

$sx = simplexml_load_string($xml);
$symbols = [];
foreach ( $sx->children('urn:schemas-microsoft-com:xml-diffgram-v1')->diffgram->children("")->Ticker->Ticker as $ticker ) {
$symbols[] = (string)$ticker->SYMBOL;
}

给你一个:

<?php
$xmldata = file_get_contents("https://egytech4uu.herokuapp.com/data.xml");
$xmlparser = xml_parser_create();
$arr = [];
xml_parse_into_struct($xmlparser, $xmldata, $arr);
xml_parser_free($xmlparser);
print_r($arr);

这是怎么回事?它返回一个平面数组,但至少对于每个节点,我们可以看到它的级别。正如在评论中提到的,这不是解析XML的最佳方法,只是万不得已的办法。

最新更新