1. #1
    Sencha User
    Join Date
    Aug 2012
    Posts
    5
    Vote Rating
    0
    ghjbym is on a distinguished road

      0  

    Default Answered: Loading store with XML Data

    Answered: Loading store with XML Data


    Hi, I'm new to Extjs and this is my first question. I'll try to be as clear as I can.

    I have an infinite grid and I have to load it with XML data not JSON.
    I created model and store and managed to load the grid with XML data.

    My store's proxy is
    proxy: {
    type: 'ajax',
    url: 'Store/FillIadeGrid',
    reader: {
    type: 'xml',
    root: 'Cekler',
    record: 'Cek'
    }
    }
    I could fill the grid with elements with 'Cek' name. But I also want to get additional elements like TakasTarihi, TotalCount etc. These elements are not related to Model, I dont want to show them in grid's columns. But I need these informations. How can I get the XML file's elements, not related to Model?


    Here is my Model
    -------------------
    Ext.define('BTOM.model.iade.TakasIadeModel', {
    extend: 'Ext.data.Model',
    fields: [
    { name: 'IadeKodu', type: 'string' },
    ...
    { name: 'Tutar', type: 'string' }
    ]
    });

    Here is my Store
    -----------------
    Ext.define('BTOM.store.iade.TakasIadeStore', {
    extend: 'Ext.data.Store',
    model: 'BTOM.model.iade.TakasIadeModel',
    autoLoad: false,

    buffered: true,
    pageSize: 200,

    proxy: {
    type: 'ajax',
    url: 'Store/FillIadeGrid',
    reader: {
    type: 'xml',
    root: 'Cekler',
    record: 'Cek'
    }
    }
    });

    Here is the XML File
    ----------------------
    <?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="..\..\XSL\ornek-10.xsl"?><ns0:TakasDagitimSonuc xmlns:ns0="http://...">
    <TakasTarihi>2012-12-03</TakasTarihi>
    <PaketTarihi>2012-01-01</PaketTarihi>
    ...
    <Cekler>
    <Cek>
    <SiraNo>481...</SiraNo>
    <CekBank>00..</CekBank>
    .
    .
    .
    </Cek>
    <Cek>
    <SiraNo>481...</SiraNo>
    <CekBank>00..</CekBank>
    .
    .
    .
    </Cek>
    ...

    And here is my .net MVC method
    ----------------------------------
    public ActionResult FillIadeGrid(string loggedUserId){
    string xmlString = "";
    using (XmlReader xr = XmlReader.Create(url, new XmlReaderSettings() { IgnoreWhitespace = true }))
    {
    using (StringWriter sw = new StringWriter())
    {
    using (XmlWriter xw = XmlWriter.Create(sw))
    {
    xw.WriteNode(xr, false);
    }
    xmlString = sw.ToString();
    }
    }
    return this.Content(xmlString, "text/xml");
    }

  2. You can add a load listener to your store and then look at store.getProxy().getReader().rawData. This will contain the raw xml document that was processed by the reader.

  3. #2
    Touch Premium Member
    Join Date
    Feb 2011
    Location
    NJ
    Posts
    311
    Answers
    59
    Vote Rating
    52
    droessner is a jewel in the rough droessner is a jewel in the rough droessner is a jewel in the rough

      0  

    Default


    You can add a load listener to your store and then look at store.getProxy().getReader().rawData. This will contain the raw xml document that was processed by the reader.

  4. #3
    Sencha User
    Join Date
    Aug 2012
    Posts
    5
    Vote Rating
    0
    ghjbym is on a distinguished road

      0  

    Default


    Thanks to you, I can access to XML elements inside the XML file content sent from server.

    store.getProxy().getReader().rawData.activeElement.childNodes[0] gives me the xml element I want.

    But, I searched and found out that, I dont have to use indexes(childNodes[0] etc.) to access specific xml elements. I learned that I can use Ext.DomQuery methods to access xml elements. As I said earlier, I'm a newbie.

    With the help of the Ext.DomQuery,
    var xmlData = store.getProxy().getReader().rawData;
    var takasTarihi = Ext.DomQuery.selectValue('TakasTarihi', xmlData);
    alert(takasTarihi);
    var cekBank = Ext.DomQuery.selectNode('Cekler/Cek/CekBank', xmlData);
    alert(cekBank.textContent);

    These two were ok.


    But when I try to access specific xml element with some condition, I can't succeed.
    For example, to select all the cek's, under cekler, with cekBank = 0010
    I know, if CekBank hadnt been an element but attribute, I could access it with this code:

    var filteredCekBank = Ext.DomQuery.selectNode('Cekler/Cek[CekBank=0010]', xmlData);
    alert(filteredCekBank.textContent);

    But it is written as sub element. So, How can I filter elements through their values?
    If you can help me with this, I would appreciate.


    XML
    ------

    ---
    <Cekler>
    <Cek>
    <CekBank>0010</CekBank>
    <SubeCode>1221</SubeCode>
    ---
    </Cek>
    </Cekler>
    ---

    I know, my error is syntax related. But I couldnt make it work.

    Thanks againg for the first problem.

  5. #4
    Touch Premium Member
    Join Date
    Feb 2011
    Location
    NJ
    Posts
    311
    Answers
    59
    Vote Rating
    52
    droessner is a jewel in the rough droessner is a jewel in the rough droessner is a jewel in the rough

      0  

    Default


    You can select nodes through their values by using the :nodeValue() selector.

    For your example, you could do something like this:
    Code:
    var filteredCekBank = Ext.DomQuery.selectNode('Cekler/Cek/CekBank:nodeValue(0010)', xmlData);
    Take a look at http://docs.sencha.com/ext-js/4-1/#!/api/Ext.dom.Query for all the valid selectors that you can use.

  6. #5
    Sencha User
    Join Date
    Aug 2012
    Posts
    5
    Vote Rating
    0
    ghjbym is on a distinguished road

      0  

    Default


    I was just looking at api. 'contains' is what I'm looking for. I should have read the api completely, before asking.
    Thanks again!

    If it's not too much, I want to ask one thing, too.

    I have to filter this infinite grid, want to filter it locally on the browser.
    I tried to use store.filterBy method.

    store.filterBy(function (rec) {
    return rec.get('SiraNo').indexOf(siraNo) > -1;
    });

    But, since pageSize of store is 200, filtering only works for the 200 rows which are on the screen at the moment of filtering.

    I can now filter the whole xml data, on the browser.
    if I can pass this filtered data to infinite grid then I may complete my infinite grid + local filtering task.

    But, I have no idea about how to pass this filtered data to infinite grid's store Efficiently.
    I may iterate through the filtered data, and pass them to a newly created store. And then I can change the infinite grid's store to this new one.

    Does this thought seem realistic to you?
    I hope you direct me about this.

    Thanks again, droessner.

  7. #6
    Touch Premium Member
    Join Date
    Feb 2011
    Location
    NJ
    Posts
    311
    Answers
    59
    Vote Rating
    52
    droessner is a jewel in the rough droessner is a jewel in the rough droessner is a jewel in the rough

      0  

    Default


    I have always done filtering on the server-side when using an infinite grid. Is there a reason why you are trying to filter the data locally? To me it makes a lot more sense to do this on the server side.

  8. #7
    Sencha User
    Join Date
    Aug 2012
    Posts
    5
    Vote Rating
    0
    ghjbym is on a distinguished road

      0  

    Default


    My grid may contain really big data, max 90000 rows.
    The user will upload an xml file, and the grid must be loaded with the content of this file.
    Then, the user will filter the grid to find one specific row and edit it. This process(filtering+editing) may repeat many times.
    So, I dont want to make too much request to server. Also security is another reason.

    I searched a way to load the grid with xml document, locally. I'll compare the performances and will decide which way to go.
    I found this.

    Model
    Code:
    Ext.define('BTOM.model.test.test', {
        extend: 'Ext.data.Model',
        fields: [
            { name: 'id', type: 'string' },
            { name: 'name', type: 'string' },
            { name: 'phone', type: 'string' }
        ]
    });
    Store
    Code:
    Ext.define('BTOM.store.test.test', {
        extend: 'Ext.data.Store',
        model: 'BTOM.model.test.test',
        autoLoad: false,
        
        proxy: {
            type: 'memory',
            reader: {
                type: 'json',
                root: 'users'
            }
        }
    });
    Grid
    Code:
    Ext.define('BTOM.view.test.test', {
        extend: 'Ext.grid.Panel',
        store: 'BTOM.store.test.test',
        alias: 'widget.test',
        title: 'Test',
    
        initComponent: function () {
    
            this.emptyText = '<b class="red">Olmadııı.</b>';
    
            this.columns =
            [
                { header: "Id", dataIndex: 'id' },
                { header: "Name", dataIndex: 'name' },
                { header: "Phone", dataIndex: 'phone'}
            ];
    
            this.callParent(arguments);
        },
    });
    Where I load the sotre is
    Code:
    this.control({
       'test': {
         render: function (grid, eOpts) {
           var store = grid.getStore();
           var data = 
           '<?xml version="1.0" encoding="utf-8"?>' +
           '<users> ' +
             '<user><id>1</id><name>Bll QASD</name><phone>333 2211</phone></user> ' +
             '<user><id>2</id><name>Asd QWF</name><phone>444 2211</phone></user> ' +
             '<user><id>3</id><name>Zas QWE</name><phone>555 2211</phone></user> ' +
           '</users>';
           var dataXml = (new DOMParser()).parseFromString(data, 'text/xml');
           store.loadRawData(dataXml);
         }
       }
    });
    I'm stuck again...
    When I watch the store on firebug, after executing the line store.loadRawData(dataXml); , store seems to be fine. it has all three user records. But the grid is empty! I controlled the dataIndex es but they are a match with model definition. I couldnt understand why the grid doesnt show the data on the screen. But firebug says grid has these records...

Thread Participants: 1

Tags for this Thread