[SOLVED] Could not extract specific Item from XML file using QXmlStreamReader !!



  • Hello Guys,

    I'm facing a problem extracting data from xml file, here is the example:
    @
    <item>
    <title>tilte 1</title>
    <link>http://example1.com</link>
    <description>description 1</description>
    <pubDate>20 Aug 2014 10:00:00 +0400</pubDate>
    </item>

    <item>
    <title>tilte 2</title>
    <link>http://example_2.com</link>
    <description>description 2</description>
    <pubDate>21 Aug 2014 10:30:00 +0400</pubDate>
    </item>

    <item>
    <title>tilte 3</title>
    <link>http://example_3.com</link>
    <description>description 3</description>
    <pubDate>20 Aug 2014 11:30:00 +0400</pubDate>
    </item>
    @

    I want to extract an <item> that contains a <pubDate> of 20 Aug 2014 using this part of code:

    @
    while(!xml.atEnd() && !xml.hasError())
    {
    /* Read next element./
    QXmlStreamReader::TokenType token = xml.readNext();
    /
    If token is just StartDocument, we'll go to next./
    if(token == QXmlStreamReader::StartDocument)
    {
    continue;
    }
    /
    If token is StartElement, we'll see if we can read it./
    if(token == QXmlStreamReader::StartElement)
    {
    /
    If it's named tv, we'll go to the next./
    if(xml.name() != "item")
    {
    continue;
    }
    /
    If it's named item, we'll dig the information from there.*/
    if(xml.name() == "item")
    {
    //Check Date
    if(this->checkItem(xml))
    {
    items.append(this->parseItem(xml));
    }
    }
    }
    }

    bool checkItem(QXmlStreamReader& xml)
    {
    if(xml.tokenType() != QXmlStreamReader::StartElement && xml.name() == "item")
    {return false;
    }

    /* Next element... */
    xml.readNext();
    /*
     * We're going to loop over the things because the order might change.
     * We'll continue the loop until we hit an EndElement named item.
     */
    while(!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == "item"))
    {
        if(xml.tokenType() == QXmlStreamReader::StartElement)
        {
            if(xml.name() == "pubDate")
            {
                //Check Date
                xml.readNext();
                if(xml.tokenType() != QXmlStreamReader::Characters)
                {
                    return false;
                }
                if(!xml.text().toString().startsWith("20 Aug 2014"))
                {
                    qDebug() << "Check Date NOK";
                    return false;
                }
                qDebug() << "output Element" << OutputElement;
                qDebug() << "Check Date OK";
            }
        }
        xml.readNext();
    }
    return true;
    

    }
    @

    The thing is the readNext() method update the reader cursor so that when returning from checkItem function I can not parse and store the checked <item> using parseItem() .

    Even when tried to use local QXmlStreamReader when using the checkItem() method , I discover that this Class could not be copied Q_DISABLE_COPY(QXmlStreamReader) !!! I just wanted to copy items that contains specific <pubDate>.

    I have also triyed to use readElementText but it appears that this method update the xml reader cursor as well.





  • [quote author="rafaelSorel" date="1408572972"]The thing is the readNext() method update the reader cursor so that when returning from checkItem function I can not parse and store the checked <item> using parseItem() .[/quote]

    Then why don't you extract the date directly in the checkItem function? The basic idea behind QXmlStreamReader is that once you've accessed the data, you cannot read it again. If you want to do this, you will have to use the QXmlDomDocument et al API.



  • :Johan Solo: Hello , I want to check the date and if it matches I have to extract the whole <item> but when I read the date it is late to extract the item because the cursor has been updated.

    :Dheerendra: I already checked the link that you have provide but it is the same case. The guy extract all the content of the xml and he doesn't make a check on any token before extract.



  • Well I have succeded to check and extract what I wanted by using QDomDocument Module:

    @
    for(int i = 0; i < nodeList.count(); i++)
    {
    // get the current one as QDomElement
    QDomElement el = nodeList.at(i).toElement();

        QDomNode pDateEntry = el.lastChild();
        if(pDateEntry.toElement().tagName() == "pubDate")
        {
            //Check date Node before proceed
            if(!pDateEntry.toElement().text().contains("Wed, 20 Aug 2014"))
            {
                qDebug() << "Date changed Finish extracting" << pDateEntry.toElement().text();
                return;
            }
        }
    
        if(!this->checkItem(el))
        {
            qDebug() << "Continue...";
            continue;
        }
        qDebug() << "Store current Item";
        items.append(this->parseItemAndStore(el));
    }
    

    @

    Thx guys for help :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.