【问题标题】:How to parse this XML using php如何使用 php 解析这个 XML
【发布时间】:2011-08-22 15:12:50
【问题描述】:

我有以下 XML (XBRL) 文件

 <xbrli:context id="I2010_ForwardContractsMember">
 <xbrli:entity>
  <xbrli:identifier scheme="http://www.sec.gov/CIK">0000027419</xbrli:identifier>
  <xbrli:segment>
    <xbrldi:explicitMember dimension="us-gaap:DerivativeByNatureAxis">us-gaap:ForwardContractsMember</xbrldi:explicitMember>
  </xbrli:segment>
</xbrli:entity>
<xbrli:period>
  <xbrli:instant>2011-01-29</xbrli:instant>
</xbrli:period>
 </xbrli:context>
<xbrli:context id="D2010Q1">
  <xbrli:entity>
  <xbrli:identifier scheme="http://www.sec.gov/CIK">0000027419</xbrli:identifier>
  </xbrli:entity>
 <xbrli:period>
    <xbrli:startDate>2010-01-31</xbrli:startDate>
    <xbrli:endDate>2010-05-01</xbrli:endDate>
  </xbrli:period>
 </xbrli:context>

我想获取id="D2010Q1"时的startDate和endDate值

我的代码如下

 $xml = new SimpleXMLElement($sec_file);
 $xml -> registerXPathNamespace('us-gaap', "http://fasb.org/us-gaap/2011-01-31");

  foreach ($xml->xpath('//xbrli:context') as $item) {

if ($item -> attributes() -> id == 'D2010Q1') {
    //print_r($item -> xpath('//xbrli:startDate'));
    echo $item->xpath('//xbrli:startDate');
    echo '<br>';
    break;
}
}

我不知道如何获取 startDate 和 endDate 值。 有什么建议吗?

原始xml位于

http://www.sec.gov/Archives/edgar/data/27419/000110465911031717/tgt-20110430.xml

【问题讨论】:

    标签: php xml xpath xml-parsing xbrl


    【解决方案1】:

    编辑:

    我需要在文件中注册所有命名空间吗?如何获取 startDate 和 endDate 信息?

    不,你只需要注册你需要的命名空间,即http://www.xbrl.org/2003/instance

    $xmldoc = new DOMDocument();
    $xmldoc->load("http://www.sec.gov/Archives/edgar/data/27419/000110465911031717/tgt-20110430.xml");
    $xpath = new DOMXPath($xmldoc);
    $xpath->registerNamespace("xbrli", "http://www.xbrl.org/2003/instance");
    $nodelist = $xpath->query("/xbrli:xbrl/xbrli:context[@id='D2010Q1']/xbrli:period"); // much faster than //xbrli:context and //xbrli:startDate
    if($nodelist->length === 1)
    {
        $period = $nodelist->item(0);
        $nodelist = $xpath->query("xbrli:startDate", $period);
        $startDate = $nodelist->length === 1 ? $nodelist->item(0)->nodeValue : null;
        $nodelist = $xpath->query("xbrli:endDate", $period);
        $endDate = $nodelist->length === 1 ? $nodelist->item(0)->nodeValue : null;
        printf("%s<br>%s", $startDate, $endDate);
    }
    else
        ; // not found or more than one <xbrli:context id='D2010Q1'><xbrli:period>
    

    旧:

    $xmldoc = new DOMDocument();
    $xmldoc->load("http://www.sec.gov/Archives/edgar/data/27419/000110465911031717/tgt-20110430.xml");
    $xpath = new DOMXPath($xmldoc);
    $xpath->registerNamespace("xbrli", "http://www.xbrl.org/2003/instance");
    $nodelist = $xpath->query("/xbrli:xbrl/xbrli:context[@id='D2010Q1']/xbrli:period/xbrli:startDate"); // much faster than //xbrli:context and //xbrli:startDate
    if($nodelist->length === 1)
        print $nodelist->item(0)->nodeValue;
    else
        ; // not found or more than one <xbrli:context id='D2010Q1'><xbrli:period>
    

    【讨论】:

    • 感谢萨克斯!我怎么知道哪个命名空间有用?例如,我使用的 xml 文件 sec.gov/Archives/edgar/data/27419/000110465911031717/… 。有很多命名空间定义。
    • @Don:对于这个特定的 XPath-Query,您只需要 xbrli XML 命名空间,因为您不需要遍历来自其他命名空间的节点。如果您想知道xlink:href 的nodeValue(第4 行),您必须注册三个命名空间:xbrlilinkxlink。您的查询可能如下所示:/xbrli:xbrl/link:schemaRef/@xlink:href。搜索XML namespaceXPath 或类似的内容,然后查看DOMXPath-Class。我还建议使用 DOMDocument 和 DOMXPath 而不是 SimpleXML,尤其是对于带有命名空间的 xml 文件。
    【解决方案2】:

    您还需要注册 xbrli 命名空间,这与您使用 us-gaap 所做的类似。 从维基百科我发现了这个 xmlns:xbrli="http://www.xbrl.org/2003/instance"

    【讨论】:

    猜你喜欢
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    • 2013-06-06
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多