【问题标题】:Parse xml caaml file with PHP用 PHP 解析 xml caaml 文件
【发布时间】:2015-12-07 13:58:22
【问题描述】:

我正在尝试使用 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> 

【问题讨论】:

    标签: php xml parsing


    【解决方案1】:

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

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

    $xpath-&gt;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..
                }
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      谢谢你的帮助,但我不能让它按照你的方式工作,但它会更好地和平:/

      我现在是这样做的:

      # 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
      
      )
      

      如果我可以让它工作,我需要分解数据,以便我可以单独使用它们。

      你有答案吗 :) 否则我使用我的版本

      感谢您的帮助!!

      【讨论】:

        猜你喜欢
        • 2012-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-05
        • 1970-01-01
        • 2012-12-22
        相关资源
        最近更新 更多