zoukankan      html  css  js  c++  java
  • Extjs GridPanel用XmlReader读取xml文件的数据 及mapping的使用规则

    Extjs中,用XmlReader可以很方便地读取xml文件数据显示在GridPanel中。需要注意是不同结构xml,取值方式有所不同。如果取节点子节点内容,则直接写子节点名称;若取节点属性,则是符号@加属性名称;若取节点内容,则留空即可。举2个例子如下:
      如果我们要读取xml数据都在节点子节点,比如:

     

    <Item>
    <Author>Sidney Sheldon</Author>
    <Title>Master of the Game</Title>
    <Manufacturer>Warner Books</Manufacturer>
    <ProductGroup>Book</ProductGroup>
    </Item>

      则XmlReader中mapping直接写子节点名称或令name与子节点名称一致,则mapping可忽略,如下:

    var store = new Ext.data.Store({
     url: ‘sheldon.xml’,
     reader: new Ext.data.XmlReader({
       record: ‘Item’
      }, [
       {name: 'Author', mapping: 'Author'},
       {name: 'Title'},
       'Manufacturer',
       'ProductGroup'
      ])
    });

      如果我们要读取xml数据有是节点内容有是节点属性,比如:

    XML语言: 知蚁博客

    <Item Author=“Sidney Sheldon” Manufacturer=“Warner Books” ProductGroup=“Book”>Master of the Game</Item>

      则XmlReader中mapping写法如下:

    {name: ‘Author’, mapping: ‘@Author’}, //取节点属性
    {name: ‘Manufacturer’, mapping: ‘@Manufacturer’},
    {name: ‘ProductGroup’, mapping: ‘@ProductGroup’}
    {name: ‘Title’, mapping: ”}, //取节点内容

      用XmlReader读取xml文件很方便吧,O(∩_∩)O~

    问:对于一个XML文件采用Ext框架,如何通过Ext提供的方法,实现对XML结构的解析?
            答:1.Ext采用例如Ext.data.JsonStore这样的store,传递url、root、fields、baseParams等参数,来获取数据 集。并且用服务器端的语言来解析XML返回{root:.......}形式的json。
                   2.包含XmlReader的普通store。
            我们重点来讨论下这个XmlReader到底怎么用。
            首先,我们得先解决这个棘手的问题:
          怎么去拿到XML中的相应node和node的集合?
            后台可以依靠XPath迅速的找到指定节点以及节点集合,Ext靠什么呢?靠的就是Ext.DomQuery。Ext的API中对它有详细的解释:
    复杂的我们先不说,先看下面的这个XML:
    <conf>
        <country name="China">
            <cid>China</cid>
                <province name="ShanXi">
                    <pid>ShanXi</pid>
                    <city>TaiYuan</city>
                    <city>DaTong</city>
                    <city>YunCheng</city>
                </province>
        </country>
        <country name="America">
            <cid>America</cid>
                <province name="Florida">
                    <pid>aaa</pid>
                    <city>bbb</city>
                    <city>ccc</city>
                    <city>ddd</city>
                </province>
        </country>
    </conf>
         那么store该怎么写呢?
        1:如果要返回所有country的数据集合:
    var store = new Ext.data.Store({
    url: 'cpc.xml',
    reader: new Ext.data.XmlReader({
    record: 'country',
    }, [
    {name: 'country', mapping: 'cid'}
    ])
    });
    2:如果要返回China下的省份数据集合:
    var store = new Ext.data.Store({
    url: 'cpc.xml',
    reader: new Ext.data.XmlReader({
    record: 'country[name=China] > province',
    }, [
    {name: 'p', mapping: 'pid'}
    ])
    });
    3:如果要返回某山西省下的所有城市:
    可以吧XML改为如下的形式:
    <conf>
    <country name="China">
    <cid>China</cid>
    <province name="ShanXi">
    <pid>ShanXi</pid>
    <city>
    <cityid>TaiYuan</cityid>
    </city>
    <city>
    <cityid>DaTong</cityid>
    </city>
    <city>
    <cityid>YunCheng</cityid>
    </city>
    </province>
    ....
    ....
    </conf>
    store为:
    var store = new Ext.data.Store({
    url: 'cpc.xml',
    reader: new Ext.data.XmlReader({
    record: 'country[name=China] > province[name=ShanXi] > city',
    }, [
    {name: 'c', mapping: 'cityid'}
    ])
    });
    有人会说,我这样都把数据写死了。是的,要想动态的改变store的内容,我们需要借助Ext为我们提供的事件和相
    应的方法。现在以combobox和grid联动为例:
    combobox显示国家名称,联动的grid里显示相应省份列表。
    我们可以这样写:
    var combobox = ..........;
    var store = new Ext.data.Store({});
    var grid = new Ext.grid.GridPanel({
    store: store,
    columns: [
    {header: "province", 120, dataIndex: 'p'}
    ],
    540,
    height:200
    });
    combobox.on('select', function(combo){
    var value = combo.getValue();
    store = new Ext.data.Store({
    url: 'cpc.xml',
    reader: new Ext.data.XmlReader({
    record: 'country[name=' + value + '] > province',
    }, [
    {name: 'p', mapping: 'pid'}
    ]);
    grid.reconfigure(store, grid.getColumnModel());
    store.load();
    });
    这里我们要注意几点:
    1,注意gridpanel的reconfigure方法,它是改换store的好工具,换了后千万别忘了load一下store哦。
    2,注意XML外面一定要包一层东西,就是上面的xml中的最外层<conf>,如果没有<conf>,是不可能取到国家数据集
    的。
    3,注意combo的mode一定要是remote啊。
    4,注意例子中的XML很特殊,mapping貌似只能对应一个node的tag,好像不可以对应一个Node的属性,这点有达人知
    道的话,回复一下在下。
    5,用firebug可以看到,不管你取到的是哪一层数据,response的永远都是xml整个文件,数据量大的时候要慎重使
    用XMLReader。(这点是废话,reader是在返回后调用的,只是一个解析器)
    6,用XMLReader在我看来,会牺牲一下XML的“个性”,需要复合DOMQuery的检索规范。它显然没有后台的XPATH那么
    强势,所以,我们在处理“细活”的时候最好利用后台代码。
     
    举个实际中的里子:
     
    • XML如下:

    <Lists>
            <List Name="ExecuteObject">
              <Item Type="Page" Body="../WFBusinessFrame/WFFrame.aspx" Parameter="测试" __STATE="" __rowNo="0" />
            </List>
            <List Name="Parameter" />
            <List Name="Incoming">
              <Item TaskId="ID10000" TaskName="办公用品申请" Method="" Condition="" />
              <Item TaskId="ID10001" TaskName="IT经理审批" Method="" Condition="" />
            </List>

    </Lists>

     
    • 代码如下,请注意标颜色的地方

      Ext.define('Executorbody', {
                extend: 'Ext.data.Model',
                fields: [
                // set up the fields mapping into the xml doc
                // The first needs mapping, the others are very basic
                    {name: 'ListName', mapping: '@Name' },
                    {name: 'Type', mapping: 'Item > @Type' },
                    { name: 'Body', mapping: 'Item > @Body' },
                    { name: 'Parameter', mapping: '@Parameter' }
                  
                ]
            });
            var store = Ext.create('Ext.data.Store', {
                model: 'Executorbody',
                autoLoad: true,
                proxy: {
                    // load using HTTP
                    type: 'ajax',
                    url: '/WebShare/Workflow/wfDefine.xml',
                    // the return will be XML, so lets set up a reader
                    reader: {
                        type: 'xml',
                        // records will have an "List" tag
                        record: "Lists > List[Name='ExecuteObject']"
                    
                    }
                }
            });
            this.grid = Ext.create('Ext.grid.Panel', {
                store: store,
               columns: [//配置表格列
                     Ext.create('Ext.grid.RowNumberer', { text: '行号', 35 }),
                    { header: "ListName", 50, dataIndex: 'ListName', sortable: true, align: "center", editor: { xtype: 'textfield'} },
                    { header: "类别", 50, dataIndex: 'Type', sortable: true, align: "center", editor: { xtype: 'textfield'} },
                    { header: "执行体", 400, dataIndex: 'Body', sortable: true, align: "center", editor: { xtype: 'textfield'} },
                    { header: "参数", 60, dataIndex: 'Parameter', sortable: true, align: "right", editor: { xtype: 'textfield'} }
                    ],
              
                840,
                height: 200
            });

     
    • 呈现结果如下:

     
    image
     
    • 剖析如下:

    •  

      我们主要是从以下xml里取出

      List Name ,Item里的 Type, Body,Parameter

    <List Name="ExecuteObject">
    <Item Type="Page" Body="../WFBusinessFrame/WFFrame.aspx" Parameter="测试" __STATE="" __rowNo="0" />
    </List>

     

    • 所以定义的record要定位到相应的地方:

               record: "Lists > List[Name='ExecuteObject']"

    • 在例子里我们是搜索所有List里Name='ExecuteObject' 的记录,所以要用以下方式进行检索,注意

      Name 是 List的属性

      如果不需要过滤,直接用List就行

    • 在例子里我们是搜索List,因此要想找到Type,body必须Mapping to 'Item > @Type'
    • 由于对Parameter 没有指定路径,因此在 结果里没能显示,

    {name: 'ListName', mapping: '@Name' },
    {name: 'Type', mapping: 'Item > @Type' },
    { name: 'Body', mapping: 'Item > @Body' },
    { name: 'Parameter', mapping: '@Parameter' }

     

     

    • 如果: 搜索Item, 如下,要想找到Type,body只需 Mapping to '@Type' 就行;

      record: "Lists > List[Name='ExecuteObject']" > Item

       

      如果是XML里的值:

    •  

      Mapping时 不要带“@”


       

       

       


       

       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
    • 相关阅读:
      Moonlight, 我看行。
      传授犯罪方法罪
      Archos TV+ 1.8.07 照样“越狱”
      写这个月的回忆记,还真少不了学车那点儿事儿
      trigger()与triggerHandler()的不同
      移除不同的
      jq中的效果
      jquery中的文档操作之一addClass append attr
      jquery中的文档操作之四
      toggle方法
    • 原文地址:https://www.cnblogs.com/dwfbenben/p/2496410.html
    Copyright © 2011-2022 走看看