2016-01-19 4 views
1

Я пытаюсь получить соответствие нескольких строк вывода XML/GML с помощью preg_match_all() из службы WFS. Я получаю кучу данных, которые доступны на общедоступном сервере для всех пользователей. Я попытался использовать s и m flag, но с небольшой удачей. данные я получаю выглядит любит это:PHP Preg_match_all на выходе XML/GML на нескольких строках

<zwr:resultaat> 
    <zwr:objectBeginTijd>2012-09-18</zwr:objectBeginTijd> 
    <zwr:resultaatHistorie> 
    <zwr:datumInvoeren>2012-10-31</zwr:datumInvoeren> 
    <zwr:invoerder> 
     <zwr:voornaam>Joep</zwr:voornaam> 
     <zwr:achternaam>Koning, de</zwr:achternaam> 
     <zwr:email>[email protected]</zwr:email> 
     <zwr:telefoon>015-2608166</zwr:telefoon> 
     <zwr:organisatie> 
     <zwr:bedrijfsnaam>Hoogheemraadschap van Delfland</zwr:bedrijfsnaam> 
     <zwr:adres> 
      <zwr:huisnummer>32</zwr:huisnummer> 
      <zwr:postcode>2611AL</zwr:postcode> 
      <zwr:straat>Phoenixstraat</zwr:straat> 
      <zwr:woonplaats>DELFT</zwr:woonplaats> 
     </zwr:adres> 
     <zwr:email>[email protected]</zwr:email> 
     <zwr:telefoon>(015) 260 81 08</zwr:telefoon> 
     <zwr:website>http://www.hhdelfland.nl/</zwr:website> 
     </zwr:organisatie> 
    </zwr:invoerder> 
    </zwr:resultaatHistorie> 
    <zwr:risicoNiveau>false</zwr:risicoNiveau> 
    <zwr:numeriekeWaarde>0.02</zwr:numeriekeWaarde> 
    <zwr:eenheid>kubieke millimeter per liter</zwr:eenheid> 
    <zwr:hoedanigheid>niet van toepassing</zwr:hoedanigheid> 
    <zwr:kwaliteitsOordeel>Normale waarde</zwr:kwaliteitsOordeel> 
    <zwr:parameterGrootheid> 
    <zwr:grootheid>Biovolume per volume eenheid</zwr:grootheid> 
    <zwr:object>Microcystis</zwr:object> 
    </zwr:parameterGrootheid> 
    <zwr:analyseProces> 
    <zwr:analyserendeInstantie>AQUON</zwr:analyserendeInstantie> 
    </zwr:analyseProces> 
</zwr:resultaat> 

Пример данных также можно найти по адресу: http://212.159.219.98/zwr-ogc/services?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetGmlObject&OUTPUTFORMAT=text%2Fxml%3B+subtype%3Dgml%2F3.1.1&TRAVERSEXLINKDEPTH=0&GMLOBJECTID=ZWR_MONSTERPUNT_304427

Это все в голландском, но это не имеет значения для контекста вопроса. Дело в том, что я хотел бы искать несколько строк этого кода и получать значения между тегами. Я также попытался прочитать все это отдельно (что получилось отлично), но поскольку существует множество комбинаций тегов (иногда используется тег или нет), это смешивает полученные данные, и в получаемой форме нет структуры данные.

Я думал, что было бы неплохо прочитать целый набор тегов, чтобы я мог хранить данные вместе. Ток preg_match_all() код у меня есть:

preg_match_all("/<zwr:risicoNiveau>(.*)<\/zwr:risicoNiveau><zwr:numeriekeWaarde>(.*)<\/zwr:numeriekeWaarde><zwr:eenheid>(.*)<\/zwr:eenheid><zwr:hoedanigheid>(.*)<\/zwr:hoedanigheid> 
    <zwr:kwaliteitsOordeel>(.*)<\/zwr:kwaliteitsOordeel><zwr:parameterGrootheid><zwr:object>(.*)<\/zwr:object><zwr:grootheid>(.*)<\/zwr:grootheid><\/zwr:parameterGrootheid>/m", $content, $stof); 

Так как вы можете видеть, что я хотел бы, чтобы прочитать несколько значений из одного preg_match_all(), это даст мне массив с множественным массива в нем.

Как читать несколько тегов друг за другом (которые находятся на разных строках?)? Когда я использую файл var_dump(), чтобы показать все данные, он показывает мне многомерный массив без данных. s и m flags не работают для меня? Я делаю что-то неправильно? Другие методы в PHP приветствуются!

+0

Почему не использует XML-анализатор? – Toto

+0

@Toto XML-анализ не работал для меня. Пространства имен - это боль **. Спасибо за ваш ответ! –

+0

Тег [tag: gml] предназначен для языка Game Maker, см. [Этот мета-пост] (http://meta.stackoverflow.com/questions/283385/gml-tag-confusion). – PGmath

ответ

1

1.) Вам нужно добавить whitespace\s между тегами.
<\/zwr:risicoNiveau>\s*<zwr:numeriekeWaarde> ...

2.) Далее использовать .*? внутри вашей группы захвата для согласования нон greedy.
<zwr:risicoNiveau>(.*?)<\/zwr:risicoNiveau>

3.) Улучшение читаемости регулярного выражения с использованием xflag (режим свободного расстояния).
Regex demo at regex101

Примечание: Используйте exclusion([^<]*?) вместо (.*?) для выгонки формат like this. Для согласования оставшихся тегов, используйте дополнительный quantifier? на дополнительных тегов like this с дополнительным <zwr:object>

$pattern = '~ 
<zwr:risicoNiveau>(.*?)</zwr:risicoNiveau>\s* 
<zwr:numeriekeWaarde>(.*?)</zwr:numeriekeWaarde>\s* 
<zwr:eenheid>(.*?)</zwr:eenheid>\s* 
<zwr:hoedanigheid>(.*?)</zwr:hoedanigheid>\s* 
<zwr:kwaliteitsOordeel>(.*?)</zwr:kwaliteitsOordeel>\s* 
<zwr:parameterGrootheid>\s* 
    <zwr:grootheid>(.*?)</zwr:grootheid>\s* 
    <zwr:object>(.*?)</zwr:object>\s* 
</zwr:parameterGrootheid> 
~sx'; 

PREG_SET_ORDER упорядочивает результаты так, что $matches[0] массив первого набора совпадений, $matches[1] представляет собой массив второй набор совпадений и т. д. ...read more in the PHP MANUAL

if(preg_match_all($pattern, $str, $out, PREG_SET_ORDER) > 0) 
    print_r($out); 

See php demo at eval.in

+0

Сэр, ты просто мне очень помог! Спасибо огромное! –

+0

Добро пожаловать @RoyanPonder! –

+0

Итак, теперь проблема заключается в том, что когда первая часть шаблона совпадает, но последняя часть не работает, она будет продолжать получать информацию до тех пор, пока не найдет последнюю часть. Это происходит потому, что содержимое в не всегда использует те же теги. Есть ли способ просто найти этот шаблон, и если он не соответствует ему, он не будет помещен в массив? –