PHP/XML - 如何读取多个子的 [英] PHP/XML - how to read multible sub's

查看:17
本文介绍了PHP/XML - 如何读取多个子的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用此 XML 文件中的所有主题值创建一个数组.ISIN 列表似乎工作正常(第一个属性值),但主题值不起作用.

I need a to create an array with all the subject values in this XML file. The ISIN list seems to work fine (the first property value), but subject values does not work.

我想最终得到一个看起来像这样的数组:

I would like to end up with a array looking something like this:

$Companys = array ( [0]  => array ( "isin" => "DK0010247014","company" => "AAB"),
                    [1]  => array ( "isin" => "DK0015250344","company" => "ALM BRAND"),
                    [2]  => array ( "isin" => "DK0015998017","company" => "BAVARIAN NORDI"),
                    [3]  => array ( "isin" => "DK0010259027","company" => "DFDS"),
                    [4]  => array ( "isin" => "DK0010234467","company" => "FLSMIDTH & CO"),
                );

这是我尝试解析的文件之一的示例:

This is an example of one of the files i am trying to parse:

<doc>
    <id>123456</id>
    <version>4.0</version>
    <consnr>7861</consnr>
    <doctype>10</doctype>
    <dest>99</dest>
    <created>2013-05-15 14:18:16</created>
    <source>Direkt-DK</source>
    <language>DA</language>
    <texttype>This is a type</texttype>
    <premium>False</premium>
    <header>This is a header</header>
    <text>
        <para format="Text">This is a paragraph</para>
        <para format="Text">This is a paragraph</para>
        <para format="Text">This is a paragraph</para>
        <para format="Text">This is a paragraph</para>
        <para format="Text"/>
        <para format="Text">This is a paragraph</para>
        <para format="Byline"/>
        <para format="Byline">contents og the by line</para>
        <para format="Byline"/>
        <para format="Byline"/>
    </text>
    <subjects>
        <subject value="AAB" weight="Main">
            <property value="DK0010247014" type2="isin" type1="identificator"/>
            <property value="CSE:AAB" type2="ticker" type1="identificator"/>
            <property type1="sector" type2="GICS" type3="1" value="25"/>
            <property type1="sector" type2="GICS" type3="2" value="2530"/>
            <property type1="sector" type2="GICS" type3="3" value="253010"/>
            <property type1="sector" type2="GICS" type3="4" value="25301030"/>
        </subject>
        <subject value="ALM BRAND" weight="Main">
            <property value="DK0015250344" type2="isin" type1="identificator"/>
            <property value="CSE:ALMB" type2="ticker" type1="identificator"/>
            <property type1="sector" type2="GICS" type3="1" value="40"/>
            <property type1="sector" type2="GICS" type3="2" value="4030"/>
            <property type1="sector" type2="GICS" type3="3" value="403010"/>
            <property type1="sector" type2="GICS" type3="4" value="40301040"/>
        </subject>
        <subject value="BAVARIAN NORDI" weight="Main">
            <property value="DK0015998017" type2="isin" type1="identificator"/>
            <property value="CSE:BAVA" type2="ticker" type1="identificator"/>
            <property type1="sector" type2="GICS" type3="1" value="35"/>
            <property type1="sector" type2="GICS" type3="2" value="3520"/>
            <property type1="sector" type2="GICS" type3="3" value="352010"/>
            <property type1="sector" type2="GICS" type3="4" value="35201010"/>
        </subject>
        <subject value="DFDS" weight="Main">
            <property value="DK0010259027" type2="isin" type1="identificator"/>
            <property value="CSE:DFDS" type2="ticker" type1="identificator"/>
            <property type1="sector" type2="GICS" type3="1" value="20"/>
            <property type1="sector" type2="GICS" type3="2" value="2030"/>
            <property type1="sector" type2="GICS" type3="3" value="203030"/>
            <property type1="sector" type2="GICS" type3="4" value="20303010"/>
        </subject>
        <subject value="FLSMIDTH & CO" weight="Main">
            <property value="DK0010234467" type2="isin" type1="identificator"/>
            <property value="CSE:FLS" type2="ticker" type1="identificator"/>
            <property type1="sector" type2="GICS" type3="1" value="20"/>
            <property type1="sector" type2="GICS" type3="2" value="2010"/>
            <property type1="sector" type2="GICS" type3="3" value="201030"/>
            <property type1="sector" type2="GICS" type3="4" value="20103010"/>
        </subject>
    </subjects>
</doc>

脚本:

<?
    foreach($xmlObj->subjects->subject as $b ){
        $isin = $b->property;
        $company = $b->attributes();
        #$company = $b->attributes()->value;
        If($isin && $isinlist == 'null') $isinlist = $isin['value'];
        ElseIf ($isin && $isinlist) $isinlist .= ','.$isin['value'];
        If($company && $companylist == 'null') $companylist = $company['value'];
        ElseIf ($company && $companylist) $companylist .= ','.$company['value'];
        var_dump($company->value[0]);
    }
?>

推荐答案

您遇到的主要问题是根据属性值查找子元素.由于有多个具有相同元素名称的子元素,因此您不能仅在名称上有所不同.

The main problem you've got is to find the child-element based on an attributes value. As there are multiple children with the same element name, you can not differ on the name alone.

在您的具体示例中,property 子项基于属性 type2="isin".

In your concrete example the property child based on the attribute type2="isin".

这可以通过使用 Xpath 来实现(这个网站已经有很多关于这个的问答材料,例如 SimpleXML:选择具有特定属性值的元素) 或通过使用一个函数来扩展 SimpleXMLElement:

This is either possible by making use of Xpath (this website already has a lot of Q&A material about that, for example SimpleXML: Selecting Elements Which Have A Certain Attribute Value) or by extending SimpleXMLElement with a function that just does it:

class MyElement extends SimpleXMLElement
{
    public function getChildByAttributeValue($name, $value) {
        foreach($this as $child)
        {
            if ($value === (string) $child[$name]) {
                return $child;
            }
        }
    }
}

然后您可以使用 MyElement 代替 SimpleXMLElement:

You can then use the MyElement instead of the SimpleXMLElement:

$xml = simplexml_load_string($buffer, 'MyElement');
                                      ###########

然后将您的值映射到数组:

and just map your values to an array:

$map = function(MyElement $subject) {
    return [
        (string) $subject['value'],
        (string) $subject->getChildByAttributeValue('type2', 'isin')['value'],
    ];
};

print_r(array_map($map, $xml->xpath('//subject')));

鉴于 $buffer 是您提供的 XML(并且已删除编码错误),这将创建以下输出:

Given that $buffer is the XML you have provided in question (and the encoding error removed), this creates the following output:

Array
(
    [0] => Array
        (
            [0] => AAB
            [1] => DK0010247014
        )

    [1] => Array
        (
            [0] => ALM BRAND
            [1] => DK0015250344
        )

    [2] => Array
        (
            [0] => BAVARIAN NORDI
            [1] => DK0015998017
        )

    [3] => Array
        (
            [0] => DFDS
            [1] => DK0010259027
        )

    [4] => Array
        (
            [0] => FLSMIDTH & CO
            [1] => DK0010234467
        )

)

完整代码示例(在线演示):

class MyElement extends SimpleXMLElement
{
    public function getChildByAttributeValue($name, $value) {
        foreach($this as $child)
        {
            if ($value === (string) $child[$name]) {
                return $child;
            }
        }
    }
}

$xml = simplexml_load_string($buffer, 'MyElement');

$map = function(MyElement $subject) {
    return [
        (string) $subject['value'],
        (string) $subject->getChildByAttributeValue('type2', 'isin')['value'],
    ];
};

print_r(array_map($map, $xml->xpath('//subject')));

这篇关于PHP/XML - 如何读取多个子的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆