XPath实例总结

常用表达式实例:

XPath 说明
/ Document Root文档根.
/* 选择文档根下面的所有元素节点,即根节点(XML文档只有一个根节点)
/node() 根元素下所有的节点(包括文本节点,注释节点等)
/text() 查找文档根节点下的所有文本节点
/messages/message messages节点下的所有message节点
/messages/message[1] messages节点下的第一个message节点
/messages/message[1]/self::node() 第一个message节点(self轴表示自身,node()表示选择所有节点)
/messages/message[1]/node() 第一个message节点下的所有子节点
/messages/message[1]/*[last()] 第一个message节点的最后一个子节点
/messages/message[1]/[last()] Error,谓词前必须是节点或节点集
/messages/message[1]/node()[last()] 第一个message节点的最后一个子节点
/messages/message[1]/text() 第一个message节点的所有子节点
/messages/message[1]//text() 第一个message节点下递归下降查找所有的文本节点(无限深度)
/messages/message[1] /child::node()  
/messages/message[1] /node()  
/messages/message[position()=1]/node()  
//message[@id=1] /node() 第一个message节点下的所有子节点
//message[@id=1] //child::node() 递归所有子节点(无限深度)
//message[position()=1]/node() 选择id=1的message节点以及id=0的message节点
/messages/message[1] /parent::* Messages节点
/messages/message[1]/body/attachments/parent::node()  
/messages/message[1]/body/attachments/parent::* /messages/message[1]/body/attachments/.. attachments节点的父节点。父节点只有一个,所以node()和* 返回结果一样。(..也表示父节点. 表示自身节点)
//message[@id=0]/ancestor::* Ancestor轴表示所有的祖辈,父,祖父等。向上递归
//message[@id=0]/ancestor-or-self::* 向上递归,包含自身
//message[@id=0]/ancestor::node() 对比使用*,多一个文档根元素(Document root)
/messages/message[1]/descendant::node()  
//messages/message[1]//node() 递归下降查找message节点的所有节点
/messages/message[1]/sender/following::* 查找第一个message节点的sender节点后的所有同级节点,并对每一个同级节点递归向下查找。
//message[@id=1]/sender/following-sibling::* 查找id=1的message节点的sender节点的所有后续的同级节点。
//message[@id=1]/datetime/@date 查找id=1的message节点的datetime节点的date属性
//message[@id=1]/datetime[@date]  
//message/datetime[attribute::date] 查找id=1的message节点的所有含有date属性的datetime节点
//message[datetime] 查找所有含有datetime节点的message节点
//message/datetime/attribute::*  
//message/datetime/attribute::node()  
//message/datetime/@* 返回message节点下datetime节点的所有属性节点
//message/datetime[attribute::*]  
//message/datetime[attribute::node()]  
//message/datetime[@*]  
//message/datetime[@node()] 选择所有含有属性的datetime节点
//attribute::* 选择根节点下的所有属性节点
//message[@id=0]/body/preceding::node() 顺序选择body节点所在节点前的所有同级节点。(查找顺序为:先找到body节点的顶级节点(根节点),得到根节点标签前的所有同级节点,执行完成后继续向下一级,顺序得到该节点标签前的所有同级节点,依次类推。)注意:查找同级节点是顺序查找,而不是递归查找。
//message[@id=0]/body/preceding-sibling::node() 顺序查找body标签前的所有同级节点。(和上例一个最大的区别是:不从最顶层开始到body节点逐层查找。我们可以理解成少了一个循环,而只查找当前节点前的同级节点)
//message[@id=1]//*[namespace::amazon] 查找id=1的所有message节点下的所有命名空间为amazon的节点。
//namespace::* 文档中的所有的命名空间节点。(包括默认命名空间xmlns:xml)
//message[@id=0]//books/*[local-name()='book'] 选择books下的所有的book节点,注意:由于book节点定义了命名空间<amazone:book>.若写成//message[@id=0]//books/book则查找不出任何节点。
//message[@id=0]//books/*[local-name()='book' and namespace-uri()='http://www.amazon. 选择books下的所有的book节点,(节点名和命名空间都匹配)
com/books/schema']  
//message[@id=0]//books/*[local-name()='book'][year>2006] 选择year节点值>2006的book节点
//message[@id=0]//books/*[local-name()='book'][1]/year>2006 指示第一个book节点的year节点值是否大于2006.返回xs:boolean: true

django开发推荐使用pycharm作编程IDE

理由如下:

  • 功能完善,无论是python,html,javascript等,代码提示功能,自动排版功能,等等都很强悍
  • 启动快,比eclipse快多了
  • 体积小,比eclipse小多了
  • 耗能小,常用笔记本电脑电池的同学,最关心这个,eclipse太耗电了,pycharm能耗跟safari那些差不多。

初学搭建cube要注意的问题

初学搭建cube时,常会发现数据不准确,跟用sql语句查询出来的不一致,这是由于里面有些东西没配置对,使得cube的运算偏离了开发者的预想

  • 维度的排序方式

    维度的排序有按name和按key等多种方式(本质上就两种),如果是数字字段的话,实际上就是字符排序和数值排序的区别了,如果不小心设成了字符排序,那么在涉及范围选择时,就会偏离开发者按数字排序取范围的预想。

  • 维度用法

    在多个维度与多个度量值组之间存在复杂关系时,维度用法的设置就非常影响cube的运算效果,“常规,事实,被引用,多对多”这几种用法的差别一定得搞清楚,建议新手多换几种对比一下。

  • mdx语句的where等并不与sql的where等价,实现类似group by的功能时,特别要注意

    ETL得做好数据的严格清洗,处理好空值数据,否则在建维度或cube时,会出现非常多类似key not found等的异常报错

使用BeautifulSoup出现中文编码异常的解决办法

UnicodeEncodeError: 'gbk' codec can't encode character u'xd0' in position 0:

几经波折,我才发现,问题都在html源串上,我的解决办法是:

传给BeautifulSoup的html先进行unicode编码。

html=urllib2.urlopen(url).read()
sp=BeautifulSoup(html.decode('gbk').encode('utf-8'))

后面再getText()时就没有乱码问题了

python pint输出到文件报UnicodeEncodeError错误的解决方法

今天在使用feedparser尝试print rss entries的title时,如果是在标准输出,没有问题,但通过管道输出到文本文件时,就报UnicodeEncodeError:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 33-51: ordinal not in range(128)

在网上搜到以下解决办法,搞掂:

在你python的安装目录下的Lib目录,找到site.py,修改def setencoding()方法

def setencoding():
   .....
   ....
    if 0:
        # Enable to support locale aware default string encodings.

把那个if 0改为if 1试试。。

http://zhidao.baidu.com/question/178416789.html

python日期加减自然月和自然年

import math,datetime
def _add_month_interval (dt,inter):
    m=dt.month+inter-1
    y=dt.year+math.floor(m/12)
    m=m % 12 +1
    return (y,m)

def add_month_interval (dt,inter):
    y,m=_add_month_interval(dt,inter)
    y2,m2=_add_month_interval(dt,inter+1)
    maxD=( datetime.date(y2,m2,1)-datetime.timedelta(days=1) ).day
    d= dt.day<=maxD and dt.day or maxD
    return datetime.date(y,m,d)

def add_year_interval (dt,inter):
    return add_month_interval(dt,inter*12)

mac terminal自动登录服务器

终端的ssh是标准的OpenSSH client

如果需要克隆会话功能,可以通过配置打开。

$ cat .ssh/config

Host *
ControlMaster auto
ControlPath ~/.ssh/%h-%p-%r
ControlPersist yes

这样每连上一个服务器都会自动在~/.ssh/下创建一个socket文件,下次用相同用户名、端口、主机名进行连接就会自动复用

===================

利用上面的特性,就可以实现二次登录免密码输入功能,再写个定制脚本,简化 ssh -p $port $user@$host 命令的执行,就能实现ssh快速登录服务器了。果然是自己动手,丰衣足食啊。

比如:myssh 241

cat myssh

#!/usr/bin/env bash
hostName=$1
port=$2
user=$3

if [ "$hostName" = "" ]
then
  echo "usage: $0 hostName [port [user]]"
  exit 1
fi

hostPref="10."

host=`echo $hostName | awk -F"." '{for(i=1;i<=4-NF;i++){ printf(hostPref);} printf($0);}' hostPref="$hostPref"`
if [ "$port" = "" ]
then
  port=16888
fi

if [ "$user" = "" ]
then
   user="denishuang"
fi

ssh -p $port $user@$host

===================

后来我用惯了Command + Shift + N(新开命令)后,上面这个脚本也就不用了,加上Command+Ctrl+T和 Command +(1,2,3,4....)后 ,发现terminal还是比SecureCRT爽多了。

登录过后,scp也不用重复输入密码了。 rz命令在一定程度上退休了。

saiku角色权限控制

  1. tomcat/webapps/saiku/WEB-INF/classes/saiku-datasources/your-cube文件中

    # some security configuration for roles, first enable it
    security.enabled=true
    
    # there are 3 different types of security:
    # "one2one" (try and map spring user roles to mondrian roles),
    # "mapping" (define the mapping of spring and mondrian roles manually)
    # "passthrough" (will pass username + password of logged in user to connection, e.g. jdbc user + password)
    
    security.type=one2one
    
    # security.type=mapping
    # security.mapping=springRole=mondrianRole1;springRole2=mondrianRole2
    
  2. tomcat/webapps/saiku/WEB-INF/users.properties

    admin=abcdefg,ROLE_USER,ROLE_ADMIN
    chenfan=1234567,ROLE_FINANCE
    xiaoqiuying=520520,ROLE_FINANCE
    
  3. cube的schema文件里,仿FoodMart.xml里的最后一段:

    <!-- A California manager can only see customers and stores in California.
         They cannot drill down on Gender. -->
    <Role name="California manager">
      <SchemaGrant access="none">
        <CubeGrant cube="Sales" access="all">
          <HierarchyGrant hierarchy="[Store]" access="custom"
              topLevel="[Store].[Store Country]">
            <MemberGrant member="[Store].[USA].[CA]" access="all"/>
            <MemberGrant member="[Store].[USA].[CA].[Los Angeles]" access="none"/>
          </HierarchyGrant>
          <HierarchyGrant hierarchy="[Customers]" access="custom"
              topLevel="[Customers].[State Province]" bottomLevel="[Customers].[City]">
            <MemberGrant member="[Customers].[USA].[CA]" access="all"/>
            <MemberGrant member="[Customers].[USA].[CA].[Los Angeles]" access="none"/>
          </HierarchyGrant>
          <HierarchyGrant hierarchy="[Gender]" access="none"/>
        </CubeGrant>
      </SchemaGrant>
    </Role>
    
    <Role name="No HR Cube">
      <SchemaGrant access="all">
        <CubeGrant cube="HR" access="none"/>
      </SchemaGrant>
    </Role>
    

Done!