views:

32

answers:

2

I have a question concerning a good strategy on how to fill a data "bean" with data inside an xml file.

The bean might look like this:

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

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

the xml subtree containing the info might look like this:

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

At the moment, I have one approach using DOMDocument. A method iterates over the entries and fills the bean by "remembering" the last node. I think thats not a good approach.

What I have in mind is something like preconstructing some xpath expression(s) and then iterate over the subtrees/nodeLists. Return an array containing the beans as defined above eventually.

However, it seems not to be possible reusing a subtree /DOMNode as DOMXPath constructor parameter.

Has anyone of you encountered such a problem?

A: 

Did you mean using an XML file as a sort of template ?

You can use some factory to build the empty person or biography node and then feed it, or validate using DTD's

You can search using xpath on selected DOM nodes, see php DOMXpath manual

Benoit
A: 

Hello Benoit,

no. The XML contains real data. I need to transform it into a php array (unfortunenatly it must be PHP :/ don't ask why ...).

---> You can use some factory to build the empty person or biography node and then feed it, or validate using DTD's

The "bean" is not the problem ... Constructing the list of beans is harder than i thought.. maybe the main problem is related to the solution, since I want to keep it as general as possible ..

here is some java code I just wrote, maybe you get an idea..

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 is just a simple iterative xml traverser .. Attribute another Bean for Value and Name.

This solution works fine, given the case there is a "person"-node.. However, the code could grow drastically for all other elements that need to be parsed..

I don't expect ready made solutions, just a small hint in the right direction.. :)

Cheers,

Mike

Mike
Maybe there is some mapping framework out there. something like JAXB, that can "serialize" php objects to xml and vice verse.
Mike