使用PHP解析xml caaml文件

时间:2015-12-07 13:58:23

标签: php xml parsing

我尝试使用CAAML标准解析xml文件。 Check it out here!

我想列出区域代码为AT7R9的所有部分

我找到了这段代码,但不知道如何解析区域代码部分:

$doc = new DOMDocument();
$doc->load('lws.xml');

$xpath = new DOMXpath($doc);
$xpath->registerNamespace("caaml", "http://caaml.org/Schemas/V5.0/Profiles/BulletinEAWS");

if ($doc->schemaValidate('http://caaml.org/Schemas/V5.0/Profiles/BulletinEAWS/CAAMLv5_BulletinEAWS.xsd')) {

    echo '<ul>'."\n";
    echo '    <li>dateTimeReport: <img src="'.$xpath->evaluate("//caaml:fileReferenceURI")->item(0)->nodeValue.'" alt="Lawinenlagebericht vom '.$xpath->evaluate("//caaml:MetaData/caaml:dateTimeReport")->item(0)->nodeValue.'"></li>'."\n";
    echo '    <li>dateTimeReport: '.$xpath->evaluate("//caaml:MetaData/caaml:dateTimeReport")->item(0)->nodeValue.'</li>'."\n";
    echo '    <li>srcRef: '.$xpath->evaluate("//caaml:MetaData/caaml:srcRef/@*[local-name()='href']")->item(0)->nodeValue.'</li>'."\n";
    echo '    <li>comment: '.$xpath->evaluate("//caaml:BulletinMeasurements/caaml:comment")->item(0)->nodeValue.'</li>'."\n";
    echo '    <li>Warnstufe R9: '.$xpath->evaluate("./caaml:locRef")->item(0)->nodeValue.'</li>'."\n";

    echo '</ul>'."\n";

}

有人可以帮我解决一下解析R9的DangerRating部分的片段吗?

这是xml部分:

    <caaml:DangerRating>
      <caaml:locRef xlink:href="AT7R9"/>
      <caaml:validTime>
        <caaml:TimePeriod>
          <caaml:beginPosition>2015-04-13T00:00:00+02:00</caaml:beginPosition>
          <caaml:endPosition>2015-04-13T11:59:59+02:00</caaml:endPosition>
        </caaml:TimePeriod>
      </caaml:validTime>
      <caaml:validElevation>
        <caaml:ElevationRange uom="m">
          <caaml:beginPosition>2200</caaml:beginPosition>
        </caaml:ElevationRange>
      </caaml:validElevation>
      <caaml:mainValue>1</caaml:mainValue>
    </caaml:DangerRating>
    <caaml:DangerRating>
      <caaml:locRef xlink:href="AT7R9"/>
      <caaml:validTime>
        <caaml:TimePeriod>
          <caaml:beginPosition>2015-04-13T00:00:00+02:00</caaml:beginPosition>
          <caaml:endPosition>2015-04-13T11:59:59+02:00</caaml:endPosition>
        </caaml:TimePeriod>
      </caaml:validTime>
      <caaml:validElevation>
        <caaml:ElevationRange uom="m">
          <caaml:endPosition>2200</caaml:endPosition>
        </caaml:ElevationRange>
      </caaml:validElevation>
      <caaml:mainValue>2</caaml:mainValue>
    </caaml:DangerRating>
    <caaml:DangerRating>
      <caaml:locRef xlink:href="AT7R9"/>
      <caaml:validTime>
        <caaml:TimePeriod>
          <caaml:beginPosition>2015-04-13T12:00:00+02:00</caaml:beginPosition>
          <caaml:endPosition>2015-04-13T23:59:59+02:00</caaml:endPosition>
        </caaml:TimePeriod>
      </caaml:validTime>
      <caaml:validElevation>
        <caaml:ElevationRange uom="m">
          <caaml:beginPosition>2800</caaml:beginPosition>
        </caaml:ElevationRange>
      </caaml:validElevation>
      <caaml:mainValue>2</caaml:mainValue>
    </caaml:DangerRating>
    <caaml:DangerRating>
      <caaml:locRef xlink:href="AT7R9"/>
      <caaml:validTime>
        <caaml:TimePeriod>
          <caaml:beginPosition>2015-04-13T12:00:00+02:00</caaml:beginPosition>
          <caaml:endPosition>2015-04-13T23:59:59+02:00</caaml:endPosition>
        </caaml:TimePeriod>
      </caaml:validTime>
      <caaml:validElevation>
        <caaml:ElevationRange uom="m">
          <caaml:endPosition>2800</caaml:endPosition>
        </caaml:ElevationRange>
      </caaml:validElevation>
      <caaml:mainValue>3</caaml:mainValue>
    </caaml:DangerRating>
    <caaml:DangerRating> 

2 个答案:

答案 0 :(得分:0)

我认为您可以将其用作xpath表达式:

$domNodeList = $xpath->evaluate("//caaml:DangerRating[descendant::caaml:locRef/@xlink:href='AT7R9']");

$xpath->evaluate将返回DOMNodeList,您可以使用foreach循环播放。

也许此设置可以帮助您:

<?php
if ($doc->schemaValidate('http://caaml.org/Schemas/V5.0/Profiles/BulletinEAWS/CAAMLv5_BulletinEAWS.xsd')) {

    $domNodeList = $xpath->evaluate("//caaml:DangerRating[descendant::caaml:locRef/@xlink:href='AT7R9']");

    // This will give you 4 DOMElement's where $dnl->nodeName is 'caaml:DangerRating'
    foreach ($domNodeList as $dnl) {

        foreach ($dnl->childNodes as $childNode) {

            // For example check if the $childNode is a DOMElement
            if ($childNode->nodeType === 1) {
                // etc..
            }
        }
    }
}

答案 1 :(得分:0)

感谢你的帮助,但是我无法让你按照自己的方式工作,但它会让代码更加安静:/

我现在这样做了:

# Setzt den Array Index wieder zurück auf 0
function fix_keys($array) {
    $numberCheck = false;
        foreach ($array as $k => $val) {
            if (is_array($val)) $array[$k] = fix_keys($val); //recurse
            if (is_numeric($k)) $numberCheck = true;
        }
            if ($numberCheck === true) {
                return array_values($array);
            } else {
                return $array;
            }
}


# XML File auslesen
$xmlfile = new DOMDocument();
$lws = array();

$xmlfile->load('lws.xml'); // Source File auslesen, Originl LWS( https://apps.tirol.gv.at/lwd/produkte/LLBTirol.xml )

$xpath = new DOMXpath($xmlfile);
$xpath->registerNamespace("caaml", "http://caaml.org/Schemas/V5.0/Profiles/BulletinEAWS");
$xpath->registerNamespace("xlink", "http://www.w3.org/1999/xlink");

# echo "Lawinenwarnstufe in den R9 Zillertaler Alpen!<br>";
foreach ($xpath->evaluate('//caaml:DangerRating') as $dangerRating) {

    $locRef = $xpath->evaluate('string(caaml:locRef/@xlink:href)', $dangerRating );

    if ($locRef == "AT7R9") {

        $seehoehe = $xpath->evaluate('string(caaml:validElevation/caaml:ElevationRange/caaml:endPosition)', $dangerRating );
        if(empty($seehoehe)){
            $lws[$i][] = "0";
        }else{      
            $lws[$i][] = $xpath->evaluate('string(caaml:validElevation/caaml:ElevationRange/caaml:endPosition)', $dangerRating );
        }
        $lws[$i][] = $xpath->evaluate('string(caaml:mainValue)', $dangerRating );
    }
    $i++;
}

# Arrayindex auf 0 setzen;
$lws = fix_keys($lws);

#### Wenn 4 Angaben vorhanden sind gilt folgender Aufbau 1+2 Vormittags / 3+4 Nachmittags
#### $lws[i][0] = Seehöheader
#### $lws[i][1] = Warnstufe
echo "Vormittag:";
echo " < ".$lws[1][0]."m = ".$lws[0][1].", "; 
echo " > ".$lws[1][0]."m = ".$lws[1][1]."; ";
echo "<br>";
echo "Nachmittag:"; 
echo " < ".$lws[3][0]."m = ".$lws[2][1].", ";
echo " > ".$lws[3][0]."m = ".$lws[3][1]."; ";

你的变体要短得多,但我不能从阵列中得到空白和空行。

# XML File auslesen
$xmlfile = new DOMDocument();
$lws = array();
$i=1;
$xmlfile->load('lws.xml'); // Source File auslesen, Originl LWS( https://apps.tirol.gv.at/lwd/produkte/LLBTirol.xml )

$xpath = new DOMXpath($xmlfile);
$xpath->registerNamespace("caaml", "http://caaml.org/Schemas/V5.0/Profiles/BulletinEAWS");
$xpath->registerNamespace("xlink", "http://www.w3.org/1999/xlink");

if ($xmlfile->schemaValidate('http://caaml.org/Schemas/V5.0/Profiles/BulletinEAWS/CAAMLv5_BulletinEAWS.xsd')) {

    $domNodeList = $xpath->evaluate("//caaml:DangerRating[descendant::caaml:locRef/@xlink:href='AT7R9']");

    // This will give you 4 DOMElement's where $dnl->nodeName is 'caaml:DangerRating'
    foreach ($domNodeList as $dnl) {

        //test output
        echo "Eintrag".$i." = ".$dnl->nodeValue."<br>";

        $lws[] = $dnl->nodeValue;
        $i++;
    }
}   
$clean_data = array_merge( array_filter($lws) );

这给我一个正确的输出如果我在foreach期间打印它但是如果我把它写成一个数组我得到这个:

Eintrag1 = 2015-04-13T00:00:00+02:00 2015-04-13T11:59:59+02:00 2200 1
Eintrag2 = 2015-04-13T00:00:00+02:00 2015-04-13T11:59:59+02:00 2200 2
Eintrag3 = 2015-04-13T12:00:00+02:00 2015-04-13T23:59:59+02:00 2800 2
Eintrag4 = 2015-04-13T12:00:00+02:00 2015-04-13T23:59:59+02:00 2800 3

Array
(
    [0] => 



              2015-04-13T00:00:00+02:00
              2015-04-13T11:59:59+02:00




              2200


          1

    [1] => 



              2015-04-13T00:00:00+02:00
              2015-04-13T11:59:59+02:00




              2200


          2

    [2] => 



              2015-04-13T12:00:00+02:00
              2015-04-13T23:59:59+02:00




              2800


          2

    [3] => 



              2015-04-13T12:00:00+02:00
              2015-04-13T23:59:59+02:00




              2800


          3

)

如果我可以让它工作,我需要爆炸数据,所以我可以单独使用它们。

你可以得到答案:)否则我使用我的版本

谢谢你的帮助!!