Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom parser for 3 level identation elements (list of list of items) #140

Closed
FrancescoQ opened this issue May 16, 2018 · 3 comments
Closed

Comments

@FrancescoQ
Copy link

FrancescoQ commented May 16, 2018

Hi i'm trying to parse with custom parsers as the attached example:

parsers.classes.txt
example.txt

my problem is when i'm trying to parse the children in my "Title" class, i receive this error.

0: We hit the end of the document prematurely. This likely means that some parser "eats" too many elements. Do not attempt to continue parsing.

I'm trying to base my code on the example "Using the XmlDeserializable interface" visible here http://sabre.io/xml/reading/

But maybe i don'understand well what's under the hood, because it fails with 3 custom deserializator when two of them use

$children = $reader->parseInnerTree(); foreach($children as $child) { if ($child['value'] instanceof Performance) { $title->performances[] = $child['value']; } }

How can parse a list of list of items?

Thank you so much!

EDIT: oh, the code where i use my custom parser is like that:

      $service = new Sabre\Xml\Service();  
      $service->elementMap = array(  
        '{}tit_info_venue' => "MyParser\Venue",  
        '{}tit_info_title' => "MyParser\Title",  
        '{}tit_info_perform' => 'MyParser\Performance',  
      )
@FrancescoQ
Copy link
Author

It seems that the problem is using the KeyValue along the parseInnerTree to get both the subelement that repeat AND the actual value of the node.. at the moment i resolved in this way, removing the keyvalue part.
Is there a better way to do this?

    $children = $reader->parseInnerTree();
    foreach($children as $child) {
      if ($child['value'] instanceof Performance) {
        $title->performances[] = $child['value'];
      }
      else {
        if ($child['name'] == '{}editName') {
          $title->editName = $child['value'];
        }
        if ($child['name'] == '{}sottoCat') {
          $title->sottoCat = $child['value'];
        }
        if ($child['name'] == '{}categoria') {
          $title->categoria = $child['value'];
        }
        if ($child['name'] == '{}numPerf') {
          $title->numPerf = $child['value'];
        }
      }

@evert
Copy link
Member

evert commented May 16, 2018

XMLReader and XMLWriter are streaming readers/writers. The implication is that you can only read once. You can't really rewind.

Your solution seems pretty reasonable though. Basically, if custom parses (like KeyValue) don't get you the information you need, you need to fall back on parseInnerTree (or the PHP XmlReader interface).

@FrancescoQ
Copy link
Author

Yeah, everything's clear now, thanks so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants