Стратегия PHP XML: парсинг DOM для заполнения "Bean" - PullRequest
0 голосов
/ 30 марта 2010

У меня есть вопрос относительно хорошей стратегии о том, как заполнять «bean» данных данными внутри XML-файла.

Боб может выглядеть так:

class Person
{
 var $id;
 var $forename = "";
 var $surname = "";
 var $bio = new Biography();
}

class Biography
{
    var $url = "";
    var $id;
}

поддерево xml, содержащее информацию, может выглядеть так:

<root>
 <!-- some more parent elements before node(s) of interest -->
  <person>
   <name pre="forename">
              Foo
   </name>
   <name pre="surname">
    Bar
   </name>
   <id>
    1254
   </id>
   <biography>
    <url>
     http://www.someurl.com
    </url>
    <id>
     5488
    </id>
   </biography>

  </person>
</root>

На данный момент у меня есть один подход, использующий DOMDocument. Метод перебирает записи и заполняет бин, «запоминая» последний узел. Я думаю, что это не очень хороший подход.

Я имею в виду что-то вроде предварительного построения некоторого xpath выражения, а затем итерации по поддеревьям / нодлистам. Вернуть массив, содержащий бины, как определено выше, в конце концов.

Однако, кажется невозможным повторное использование поддерева / DOMNode в качестве параметра конструктора DOMXPath.

Кто-нибудь из вас сталкивался с такой проблемой?

Ответы [ 2 ]

0 голосов
/ 30 марта 2010

нет. XML содержит реальные данные. Мне нужно преобразовать его в массив php (к сожалению, это должен быть PHP: / не спрашивайте, почему ...).

---> Вы можете использовать фабрику для создания пустого человека или узла биографии, а затем передать его или проверить с помощью DTD

"Бин" не проблема ... Построить список бинов сложнее, чем я думал .. возможно, основная проблема связана с решением, так как я хочу сделать его как можно более общим ..

вот код Java, который я только что написал, может быть, у вас есть идея ..

public List<PersonBean> extract(String xml) throws Exception {
    InputSource is =new InputSource(new StringReader(xml));
    XPathFactory xfactory = XPathFactory.newInstance();
    XPath xpath = xfactory.newXPath();
    NodeList nodeList = (NodeList)xpath.evaluate("/root/person", is, XPathConstants.NODESET);
    int length = nodeList.getLength();
    int pos = -1;
    Traverser tra = new Traverser();
    Attribute nameAttr = new Attribute();
    nameAttr.setName("attr");
    while(++pos < length) {
        PersonBean bean = new PersonBean();
        Node person = nodeList.item(pos);
        Node fore = tra.getElementByNodeName(person, "id");
        nameAttr.setValue("forename");
        Node pre = tra.getElementByNodeNameWithAttribute(person,"name",nameAttr);
        nameAttr.setValue("surname");
        Node sur = tra.getElementByNodeNameWithAttribute(person, "name", nameAttr);
        bean.setForeName(pre.getTextContent());
        bean.setSurName(sur.getTextContent());
        bean.setId(fore.getTextContent());
        Node bio = tra.getElementByNodeName(person, "biography");
        Node bid = tra.getElementByNodeName(bio, "id");
        Node url = tra.getElementByNodeName(bio, "url");
        BiographyBean bioBean = new BiographyBean();
        bioBean.setId(bid.getTextContent());
        bioBean.setUrl(url.getTextContent());
        bean.setBio(bioBean);
        persons.add(bean);
    }
    return persons;
}

Traverser - это простой итеративный xml traverser. Атрибут другого компонента для значения и имени.

Это решение отлично работает, учитывая случай, когда существует "person" -узел. Однако код может резко возрасти для всех других элементов, которые необходимо проанализировать ..

Я не ожидаю готовых решений, просто небольшой намек в правильном направлении ..:)

Приветствия

Mike

0 голосов
/ 30 марта 2010

Вы имели в виду использование файла XML в качестве шаблона?

Вы можете использовать какую-то фабрику для создания пустого человека или узла биографии, а затем кормить его или проверять, используя DTD's

Вы можете выполнять поиск с использованием xpath на выбранных узлах DOM, см. php Руководство по DOMXpath

...