【问题标题】:Parse complex, nested, prefixed XML nodes in PHP using XMLReader使用 XMLReader 在 PHP 中解析复杂的、嵌套的、带前缀的 XML 节点
【发布时间】:2014-10-28 18:02:19
【问题描述】:

这几天我一直在搜索、阅读和尝试解析我的 XML 文件,但到目前为止还没有运气。这是我的一个 XML 文件的示例:

<?xml version="1.0" encoding="windows-1252"?>
<?xml-stylesheet type="text/xsl" href="/rss/styles/shared_xsl_stylesheet_v2.xml"?>
<rss version="2.0">
    <channel>
        <title>All XBRL Data Submitted to the SEC for 2014-10</title>
        <link>http://www.sec.gov/spotlight/xbrl/filings-and-feeds.shtml</link>
        <atom:link href="http://www.sec.gov/Archives/edgar/monthly/xbrlrss-2014-10.xml" rel="self" type="application/rss+xml" xmlns:atom="http://www.w3.org/2005/Atom"/>
        <description>This is a list all of the filings containing XBRL for 2014-10</description>
        <language>en-us</language>
        <pubDate>Mon, 27 Oct 2014 00:00:00 EDT</pubDate>
        <lastBuildDate>Mon, 27 Oct 2014 00:00:00 EDT</lastBuildDate>
        <item>
            <title>Bling Marketing, Inc. (0001593549) (Filer)</title>
            <link>http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/0001014897-14-000441-index.htm</link>
            <guid>http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/0001014897-14-000441-xbrl.zip</guid>
            <enclosure url="http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/0001014897-14-000441-xbrl.zip" length="30761" type="application/zip" />
            <description>10-Q</description>
            <pubDate>Mon, 27 Oct 2014 17:25:14 EDT</pubDate>
            <edgar:xbrlFiling xmlns:edgar="http://www.sec.gov/Archives/edgar">
                <edgar:companyName>Bling Marketing, Inc.</edgar:companyName>
                <edgar:formType>10-Q</edgar:formType>
                <edgar:filingDate>10/27/2014</edgar:filingDate>
                <edgar:cikNumber>0001593549</edgar:cikNumber>
                <edgar:accessionNumber>0001014897-14-000441</edgar:accessionNumber>
                <edgar:fileNumber>333-192997</edgar:fileNumber>
                <edgar:acceptanceDatetime>20141027172514</edgar:acceptanceDatetime>
                <edgar:period>20140930</edgar:period>
                <edgar:assistantDirector>2</edgar:assistantDirector>
                <edgar:assignedSic>5094</edgar:assignedSic>
                <edgar:fiscalYearEnd>1231</edgar:fiscalYearEnd>
                <edgar:xbrlFiles>
                    <edgar:xbrlFile edgar:sequence="1" edgar:file="bling10q3q14v2.htm" edgar:type="10-Q" edgar:size="174242" edgar:description="FORM 10-Q" edgar:url="http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/bling10q3q14v2.htm" />
                    <edgar:xbrlFile edgar:sequence="2" edgar:file="bling10q3q14ex31.htm" edgar:type="EX-31" edgar:size="5481" edgar:description="EXHIBIT 31" edgar:url="http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/bling10q3q14ex31.htm" />
                    <edgar:xbrlFile edgar:sequence="3" edgar:file="bling10q3q14ex32.htm" edgar:type="EX-32" edgar:size="1827" edgar:description="EXHIBIT 32" edgar:url="http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/bling10q3q14ex32.htm" />
                    <edgar:xbrlFile edgar:sequence="4" edgar:file="blmi-20140930.xml" edgar:type="EX-101.INS" edgar:size="149179" edgar:description="XBRL INSTANCE DOCUMENT" edgar:url="http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/blmi-20140930.xml" />
                    <edgar:xbrlFile edgar:sequence="5" edgar:file="blmi-20140930.xsd" edgar:type="EX-101.SCH" edgar:size="28373" edgar:description="XBRL TAXONOMY EXTENSION SCHEMA DOCUMENT" edgar:url="http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/blmi-20140930.xsd" />
                    <edgar:xbrlFile edgar:sequence="6" edgar:file="blmi-20140930_cal.xml" edgar:type="EX-101.CAL" edgar:size="7021" edgar:description="XBRL TAXONOMY EXTENSION CALCULATION LINKBASE DOCUMENT" edgar:url="http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/blmi-20140930_cal.xml" />
                    <edgar:xbrlFile edgar:sequence="7" edgar:file="blmi-20140930_def.xml" edgar:type="EX-101.DEF" edgar:size="17205" edgar:description="XBRL TAXONOMY EXTENSION DEFINITION LINKBASE DOCUMENT" edgar:url="http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/blmi-20140930_def.xml" />
                    <edgar:xbrlFile edgar:sequence="8" edgar:file="blmi-20140930_lab.xml" edgar:type="EX-101.LAB" edgar:size="74477" edgar:description="XBRL TAXONOMY EXTENSION LABEL LINKBASE DOCUMENT" edgar:url="http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/blmi-20140930_lab.xml" />
                    <edgar:xbrlFile edgar:sequence="9" edgar:file="blmi-20140930_pre.xml" edgar:type="EX-101.PRE" edgar:size="67806" edgar:description="XBRL TAXONOMY EXTENSION PRESENTATION LINKBASE DOCUMENT" edgar:url="http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/blmi-20140930_pre.xml" />
                </edgar:xbrlFiles>
            </edgar:xbrlFiling>
        </item>
        <item>
            <title>Primco Management Inc. (0001516522) (Filer)</title>
            <link>http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/0001014897-14-000414-index.htm</link>
            <guid>http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/0001014897-14-000414-xbrl.zip</guid>
            <enclosure url="http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/0001014897-14-000414-xbrl.zip" length="80939" type="application/zip" />
            <description>10-K/A</description>
            <pubDate>Tue, 30 Sep 2014 17:41:38 EDT</pubDate>
            <edgar:xbrlFiling xmlns:edgar="http://www.sec.gov/Archives/edgar">
                <edgar:companyName>Primco Management Inc.</edgar:companyName>
                <edgar:formType>10-K/A</edgar:formType>
                <edgar:filingDate>10/01/2014</edgar:filingDate>
                <edgar:cikNumber>0001516522</edgar:cikNumber>
                <edgar:accessionNumber>0001014897-14-000414</edgar:accessionNumber>
                <edgar:fileNumber>000-54930</edgar:fileNumber>
                <edgar:acceptanceDatetime>20140930174138</edgar:acceptanceDatetime>
                <edgar:period>20131231</edgar:period>
                <edgar:assistantDirector>8</edgar:assistantDirector>
                <edgar:assignedSic>6531</edgar:assignedSic>
                <edgar:fiscalYearEnd>1231</edgar:fiscalYearEnd>
                <edgar:xbrlFiles>
                    <edgar:xbrlFile edgar:sequence="1" edgar:file="primco10k13am2v2.htm" edgar:type="10-K/A" edgar:size="482147" edgar:description="FORM 10-K/A" edgar:url="http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/primco10k13am2v2.htm" />
                    <edgar:xbrlFile edgar:sequence="2" edgar:file="primco10k13ex31.htm" edgar:type="EX-31" edgar:size="10412" edgar:description="EXHIBIT 31" edgar:url="http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/primco10k13ex31.htm" />
                    <edgar:xbrlFile edgar:sequence="3" edgar:file="primco10k13ex32.htm" edgar:type="EX-32" edgar:size="3121" edgar:description="EXHIBIT 32" edgar:url="http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/primco10k13ex32.htm" />
                    <edgar:xbrlFile edgar:sequence="4" edgar:file="pmcm-20131231.xml" edgar:type="EX-101.INS" edgar:size="891933" edgar:description="XBRL INSTANCE DOCUMENT" edgar:url="http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/pmcm-20131231.xml" />
                    <edgar:xbrlFile edgar:sequence="5" edgar:file="pmcm-20131231.xsd" edgar:type="EX-101.SCH" edgar:size="54127" edgar:description="XBRL TAXONOMY EXTENSION SCHEMA DOCUMENT" edgar:url="http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/pmcm-20131231.xsd" />
                    <edgar:xbrlFile edgar:sequence="6" edgar:file="pmcm-20131231_cal.xml" edgar:type="EX-101.CAL" edgar:size="12529" edgar:description="XBRL TAXONOMY EXTENSION CALCULATION LINKBASE DOCUMENT" edgar:url="http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/pmcm-20131231_cal.xml" />
                    <edgar:xbrlFile edgar:sequence="7" edgar:file="pmcm-20131231_def.xml" edgar:type="EX-101.DEF" edgar:size="77249" edgar:description="XBRL TAXONOMY EXTENSION DEFINITION LINKBASE DOCUMENT" edgar:url="http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/pmcm-20131231_def.xml" />
                    <edgar:xbrlFile edgar:sequence="8" edgar:file="pmcm-20131231_lab.xml" edgar:type="EX-101.LAB" edgar:size="146832" edgar:description="XBRL TAXONOMY EXTENSION LABEL LINKBASE DOCUMENT" edgar:url="http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/pmcm-20131231_lab.xml" />
                    <edgar:xbrlFile edgar:sequence="9" edgar:file="pmcm-20131231_pre.xml" edgar:type="EX-101.PRE" edgar:size="131110" edgar:description="XBRL TAXONOMY EXTENSION PRESENTATION LINKBASE DOCUMENT" edgar:url="http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/pmcm-20131231_pre.xml" />
                </edgar:xbrlFiles>
            </edgar:xbrlFiling>
        </item>
    </channel>
</rss>

XML 文件大约 30MB,用 simpleXML 解析应该没问题,但问题在于 simpleXML 无法处理像 &lt;edgar:formType&gt; 这样的标签。猜猜它们不够“简单”;-)

因此我尝试使用 XMLReader 进行解析, 能够解析这些标签。例如:

// Initialize XMLReader and DOMdocument
$reader = new XMLReader();
$reader->open("file.xml");

$storage = array();

// Move to the first <item> node
while ($reader->read() && $reader->name !== "item");

// Loop through the entire instance document
while ( $reader->read() ) {

    // Ensure that nodeType is an Element and not an Attribute or Text
    if($reader->nodeType == XMLReader::ELEMENT) {
        // Extract and store filing info in $storage array
        switch ($reader->localName) {
          case "formType":
            $reader->read();
            $storage["formType"] = $reader->value;
            break;
          case "cikNumber":
            $reader->read();
            $storage["cik"] = $reader->value;
            break;
          default:
            break;
        }       
    echo "<pre>"; print_r($storage); echo "</pre>";
    }
}

print_r 虽然返回了很多空的和重复的结果..

我想遍历每个&lt;item&gt;并使用 MySQLi 存储以下数据点:

  • &lt;guid&gt;
  • &lt;edgar:companyName&gt;
  • &lt;edgar:formType&gt;
  • &lt;edgar:filingDate&gt;
  • &lt;edgar:cikNumber&gt;
  • &lt;edgar:accessionNumber&gt;
  • &lt;edgar:period&gt;
  • &lt;edgar:fiscalYearEnd&gt;
  • edgar:url 属性&lt;edgar:xbrlFile&gt; 节点如果属性edgar:description = "XBRL 实例文档"

我觉得我已经很接近了,因为我已经能够基于localName(它针对edgar: 之后的部分)提取值,但我不知道如何访问属性以及如何访问将每个&lt;item&gt; 的数据存储在我的数据库中。

非常感谢这里的帮助,因为我在网上找到的示例都没有显示如何处理这些带前缀的 XML 标记。提前致谢!

尼克

【问题讨论】:

  • 尝试 item->children('edgar', true)->... 来解析它们。我认为这将允许您使用 simplexml
  • 哇,吉姆,你是个英雄!所以,这么简单……完全错过了那个方法。浪费了好几天哈哈,谢谢你的回复!我应该能够自己弄清楚其余的。
  • @kregus 供将来参考,标签上的“前缀”称为命名空间——如果您不知道正确的术语,很难找到有关事物的文档! :^)
  • @kregus 我把它作为答案,如果你能接受,那就太好了。很高兴它对你有用。
  • @i 惊动了外星人:太真实了!我遇到了几次“命名空间”这个词,但直到你们拯救了这一天,才把这些点联系起来,谢谢!

标签: php xml xmlreader


【解决方案1】:

尝试 item->children('edgar', true)->... 来解析它们。我认为这将允许您使用 simplexml。 edgar: 被称为命名空间,在 xml 文件中使用得相当多。不久前我遇到了同样的问题,这为我解决了,

【讨论】:

    【解决方案2】:

    由于您最初尝试使用 SimpleXML 执行此操作,因此这里有一个使用 simpleXML 解析 XML 的解决方案,特别是它的 xpath method,它为您提供了一种非常简单、方便的方法来选择 XML 文档中的节点。大多数

    # you will probably be loading the XML from a file here rather than a string...
    $sxe = simplexml_load_string( $xml );
    
    # this xpath looks for "item" elements that are under the "channel" element    
    foreach ($sxe->xpath("channel/item") as $i) {
    
        # for this example, I'll just store the data and print it after parsing each item
        $data = array();
    
        # cast the node as a string
        $data['guid'] = (string)$i->guid;
    
        # register the URI associated with the 'edgar' namespace
        # tags can be referred to using "e:tagName" from now on
        $i->registerXPathNamespace("e", "http://www.sec.gov/Archives/edgar");
    
        foreach ( array("companyName", "formType", "filingDate", "cikNumber",
            "accessionNumber", "period", "fiscalYearEnd") as $tag) {
            # create the xpath dynamically from the tag name. All tags are under the "item"
            # node ($i) under the parent edgar:xbrlFiling (i.e. e:xbrlFiling)
            $data[ $tag ] = (string)$i->xpath("e:xbrlFiling/e:$tag")[0];
        }
    
        # this searches for e:xbrlFile nodes with description "XBRL INSTANCE DOCUMENT"
        # the final /@e:url returns the e:url attribute, rather than the node itself 
        foreach ($i->xpath(
      "e:xbrlFiling/e:xbrlFiles/e:xbrlFile[@e:description='XBRL INSTANCE DOCUMENT']/@e:url"
                               ) as $url) {
            # you may want to use an array here if there are several such URLs
            $data['url'] = (string)$url;
        }
        print_r($data);
    }
    

    输出:

    Array
    (
        [guid] => http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/0001014897-14-000441-xbrl.zip
        [companyName] => Bling Marketing, Inc.
        [formType] => 10-Q
        [filingDate] => 10/27/2014
        [cikNumber] => 0001593549
        [accessionNumber] => 0001014897-14-000441
        [period] => 20140930
        [fiscalYearEnd] => 1231
        [url] => http://www.sec.gov/Archives/edgar/data/1593549/000101489714000441/blmi-20140930.xml
    )
    Array
    (
        [guid] => http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/0001014897-14-000414-xbrl.zip
        [companyName] => Primco Management Inc.
        [formType] => 10-K/A
        [filingDate] => 10/01/2014
        [cikNumber] => 0001516522
        [accessionNumber] => 0001014897-14-000414
        [period] => 20131231
        [fiscalYearEnd] => 1231
        [url] => http://www.sec.gov/Archives/edgar/data/1516522/000101489714000414/pmcm-20131231.xml
    )
    

    【讨论】:

    • 感谢您的详细解答!我确实探索了 XPath 作为替代选项,但无法找出提取所需节点的正确语法。不过,它可能会帮助其他偶然发现此线程的人,非常感谢!
    • 我发现它比使用node-&gt;children 更容易——你可以直接指定你想要的节点,如果你想获得具有特定属性或值的节点,它非常强大。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-25
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    相关资源
    最近更新 更多