首页 > 解决方案 > 读取 XML 子属性 PHP

问题描述

我正在尝试访问我的 XML 的子属性。

这是我的 XML:

<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2">
<csw:Record>
<dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/">8b511d58-5be8-4281-b932-5954dde667cd</dc:identifier>
<dc:title xmlns:dc="http://purl.org/dc/elements/1.1/">Temperature dalle stazioni meteorologiche siciliane</dc:title>
<dc:type xmlns:dc="http://purl.org/dc/elements/1.1/">dataset</dc:type>
<dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">temperatura</dc:subject>
<dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">sicilia</dc:subject>
<dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">environment</dc:subject>
<dct:abstract xmlns:dct="http://purl.org/dc/terms/">Dataset delle misurazioni effettuate dalle stazioni meteorologiche distribuite sul territorio della regione Sicilia in merito alla temperatura. Le misurazioni sono registrate con una frequenza di 5 minuti.</dct:abstract>
<dc:description xmlns:dc="http://purl.org/dc/elements/1.1/">Dataset delle misurazioni effettuate dalle stazioni meteorologiche distribuite sul territorio della regione Sicilia in merito alla temperatura. Le misurazioni sono registrate con una frequenza di 5 minuti.</dc:description>
<dc:rights xmlns:dc="http://purl.org/dc/elements/1.1/">copyright</dc:rights>
<dc:rights xmlns:dc="http://purl.org/dc/elements/1.1/">otherRestrictions</dc:rights>
<dc:language xmlns:dc="http://purl.org/dc/elements/1.1/">ita</dc:language>
<ows:BoundingBox xmlns:ows="http://www.opengis.net/ows" crs="urn:ogc:def:crs:EPSG:6.6:4326">
<ows:LowerCorner>15.5877 36.3799</ows:LowerCorner>
<ows:UpperCorner>11.5864 38.979</ows:UpperCorner>
</ows:BoundingBox>
<dc:URI xmlns:dc="http://purl.org/dc/elements/1.1/" protocol="OGC:WMS" name="Temperature stazioni siciliane 2015-05-01" description="Servizio di visualizzazione WMS">http://localhost:8080/geoserver/ewas/wms?service=WMS&version=1.1.0&request=GetMap&layers=ewas%3Adeg_temperature_2015_05_01&bbox=2246931.5%2C4058390.75%2C2574061.5%2C4269145.5&width=768&height=494&srs=EPSG%3A3004&styles=&format=application/openlayers</dc:URI>
<dc:URI xmlns:dc="http://purl.org/dc/elements/1.1/" protocol="OGC:WMS" name="Sicilia comuni confini">http://localhost:8080/geoserver/ewas/wms?service=WMS&version=1.1.0&request=GetMap&layers=ewas%3Asicilia_comuni&bbox=2244086.25%2C4054129.25%2C2578859.75%2C4297079.5&width=768&height=557&srs=EPSG%3A3004&styles=&format=application/openlayers</dc:URI>
</csw:Record>
</csw:GetRecordByIdResponse>

我目前正在使用 PHP 中的以下代码访问子节点:

$xml = simplexml_load_string($response);  
$parsercsw = $xml->children('csw', true);
$identifier = $parsercsw->Record->children('dc', true);
$json = json_encode($identifier);
$array = json_decode($json,TRUE);

$response我有上面的 XML 中,然后我使用$parsercsw = $xml->children('csw', true);首先访问 csw 子节点,然后$identifier = $parsercsw->Record->children('dc', true);访问 csw:Record 下的所有 dc 节点。

最后使用 json_encode 和 json_decode 创建我的 PHP 数组,然后我可以获得所有 dc 节点值。

如果我打印 $array 值,我将得到以下结果:

print_r($array);
    Array
    (
    [identifier] => 8b511d58-5be8-4281-b932-5954dde667cd
    [title] => Temperature dalle stazioni meteorologiche siciliane
    [type] => dataset
    [subject] => Array
        (
            [0] => temperatura
            [1] => sicilia
            [2] => environment
        )

    [description] => Dataset delle misurazioni effettuate dalle stazioni meteorologiche distribuite sul 
  territorio della regione Sicilia in merito alla temperatura. Le misurazioni sono registrate con una frequenza di 5 minuti.
    [rights] => Array
        (
            [0] => copyright
            [1] => otherRestrictions
        )

    [language] => ita
    [URI] => Array
        (
            [0] => http://localhost:8080/geoserver/eWAS/wms?service=WMS&version=1.1.0&request=GetMap&layers=eWAS%3Adeg_temperature_2015_05_01&bbox=2246931.5%2C4058390.75%2C2574061.5%2C4269145.5&width=768&height=494&srs=EPSG%3A3004&styles=&format=application/openlayers
            [1] => http://localhost:8080/geoserver/eWAS/wms?service=WMS&version=1.1.0&request=GetMap&layers=eWAS%3Asicilia_comuni_confini&bbox=2244086.25%2C4054129.25%2C2578859.75%2C4297079.5&width=768&height=557&srs=EPSG%3A3004&styles=&format=application/openlayers
        )

)

通过这种方式,我可以访问我需要的所有值:

$uri = $array["URI"];

我的问题是我还想在 XML 中读取 dc:URI 的属性“名称”,但我不知道如何做到这一点,我尝试了不同的方法,但没有一个有效。有人可以帮帮我吗?谢谢

标签: phpxmlxml-parsingsimplexml

解决方案


这是你出错的地方:

最后用 json_encode 和 json_decode 我创建了我的 PHP 数组......

您不想要一个 PHP 数组,您想要一个可以让您访问 XML 的对象——您已经拥有了!删除那个可怕的json_encode/ json_decodehack,并阅读手册中的示例这个参考问题

这是一些示例代码(使用简化的 XML 以节省空间,并且因为您发布的内容不是有效的 XML)。

$response = <<<EOF
<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2">
<csw:Record>
<dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/">8b511d58-5be8-4281-b932-5954dde667cd</dc:identifier>
<dc:URI xmlns:dc="http://purl.org/dc/elements/1.1/" protocol="OGC:WMS" name="Temperature stazioni siciliane 2015-05-01" description="Servizio di visualizzazione WMS">https://example.com/first-link</dc:URI>
<dc:URI xmlns:dc="http://purl.org/dc/elements/1.1/" protocol="OGC:WMS" name="Sicilia comuni confini">https://example.com/second-link</dc:URI>
</csw:Record>
</csw:GetRecordByIdResponse>
EOF;


// Define your own names for namespaces, don't rely on remote XML always assigning the same prefixes
const XMLNS_CSW = 'http://www.opengis.net/cat/csw/2.0.2';
const XMLNS_DC = 'http://purl.org/dc/elements/1.1/';

$xml = simplexml_load_string($response);  

$parsercsw = $xml->children(XMLNS_CSW);
// You'd called this variable $identifier, but it's actually all the elements in that namespace
$dcElements = $parsercsw->Record->children(XMLNS_DC);
// This is how you'd get the identifier element
$identifier = $dcElements->identifier;

// Loop over the URI elements, as objects
foreach ( $dcElements->URI as $uriElement ) {
    // Get the string content with (string)
    $uri = (string)$uriElement;
    // Attributes with no prefix technically aren't in any namespace (blame the authors of the XML namespace spec)
    // So we need to select the namespace with an empty name
    $attributesWithNoNamespace = $uriElement->attributes(null);
    // Now we can access them with either ['foo'] or ->foo syntax, remembering to cast to string rather than object
    $name = (string)$attributesWithNoNamespace['name'];
    
    echo "The URI named '$name' is '$uri'\n";
}

推荐阅读