在PHP中解析XML命名空间和模式

时间:2017-12-08 10:07:20

标签: php simplexml

我知道有很多类似的帖子,但我无法成功实施任何建议。

我有以下数据提取 - XML有两个可用的数据集here

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
  <message:MessageGroup xmlns:message="http://www.SDMX.org/resources/SDMXML/schemas/v1_0/message" xmlns:common="http://www.SDMX.org/resources/SDMXML/schemas/v1_0/common" xmlns:frb="http://www.federalreserve.gov/structure/compact/common" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.SDMX.org/resources/SDMXML/schemas/v1_0/message SDMXMessage.xsd http://www.federalreserve.gov/structure/compact/common frb_common.xsd">

      <?frb EmbargoDate="2017-10-24T00:00:00"?>    

  <frb:DataSet id="Yields" xmlns:kf="http://www.federalreserve.gov/structure/compact/Yields_Yields" xsi:schemaLocation="http://www.federalreserve.gov/structure/compact/Yields_Yields Yields_Yields.xsd">
  </frb:DataSet>

  <frb:DataSet id="Yields" xmlns:kf="http://www.federalreserve.gov/structure/compact/Yields_Parameters" xsi:schemaLocation="http://www.federalreserve.gov/structure/compact/Yields_Parameters Yields_Parameters.xsd">
    <kf:Series BT="Nominal" CURRENCY="NA" FREQ="9" Parameter="B0" SERIES_NAME="BETA0" UNIT="Number" UNIT_MULT="1">
      <frb:Annotations>
        <common:Annotation>
          <common:AnnotationType>Short Description</common:AnnotationType>
          <common:AnnotationText>Beta0 Coefficient for Nominal Treasury Yields as Estimated by the Svensson Term Structure Model</common:AnnotationText>
        </common:Annotation>
      </frb:Annotations>
      <frb:Obs OBS_STATUS="A" OBS_VALUE="3.91760612" TIME_PERIOD="1961-06-14"/>
      <frb:Obs OBS_STATUS="A" OBS_VALUE="3.97849787" TIME_PERIOD="1961-06-15"/>
      <frb:Obs OBS_STATUS="A" OBS_VALUE="3.98435045" TIME_PERIOD="1961-06-16"/>
      <frb:Obs OBS_STATUS="A" OBS_VALUE="4.00437935" TIME_PERIOD="1961-06-19"/>
      <frb:Obs OBS_STATUS="A" OBS_VALUE="3.98578922" TIME_PERIOD="1961-06-20"/>
      <frb:Obs OBS_STATUS="A" OBS_VALUE="4.00405894" TIME_PERIOD="1961-06-21"/>
      <frb:Obs OBS_STATUS="A" OBS_VALUE="4.00089634" TIME_PERIOD="1961-06-22"/>
    </kf:Series>
  </frb:DataSet>
</message:MessageGroup>

YieldsParameters.xsd文件提取:

xmlns:frb="http://www.federalreserve.gov/structure/compact/common">
<xs:import namespace="http://www.federalreserve.gov/structure/compact/common" schemaLocation="frb_common.xsd"/>

我有兴趣从第二个数据集中检索OBS_VALUE和TIME_PERIOD属性。我还想计算一系列的观察结果。

使用following suggestion我的示例代码如下所示:

$myFileXml = 'feds200628.xml';
$xml = simplexml_load_file($myFileXml);

$xml->DataSet[1]->Series[0] as $Ser
$ns_dc = $Ser ->children('http://www.federalreserve.gov/structure/compact/common');
echo $ns_dc->Obs[0]->->Attributes()->OBS_VALUE;

echo $count = count($xml->children('http://www.federalreserve.gov/structure/compact/common',true)->DataSet[1]->Series[0]->Obs);

考虑到我没有检索观察值并且计数返回0,我相信我在这里遗漏了一些非常基本的东西。

我觉得很奇怪
print_r($xml); 

返回:

SimpleXMLElement对象([frb] =&gt; SimpleXMLElement对象() [评论] =&gt; SimpleXMLElement Object())

1 个答案:

答案 0 :(得分:2)

您尝试的方法存在相当多的问题,此方法使用XPath来查找您之后的数据,这消除了移动DOM以查找数据的大量需求。 XPath的主要功能是注册命名空间以允许您在查询中使用它们。

$myFileXml = 'feds200628.xml';
$xml = simplexml_load_file($myFileXml);
$xml->registerXPathNamespace('frb', 'http://www.federalreserve.gov/structure/compact/common');
$xml->registerXPathNamespace('kf', "http://www.federalreserve.gov/structure/compact/Yields_Parameters");
$ns_dc = $xml->xpath("//frb:DataSet[2]/kf:Series[1]/frb:Obs");
echo $ns_dc[0]->Attributes()->OBS_VALUE.PHP_EOL;
$count = count($ns_dc);
echo $count.PHP_EOL;

XPath只返回Obs元素(请注意,XPath数组是基于1的,而PHP数组是基于0的 - 这就是我使用2来获取第二个元素的原因。)