在Linq to XML中根据元素属性合成XPath字符串进行查询

目标:

           实现类似于SQL的where条件方式从XML中查询出满足指定属性值的元素集合,并可通用到其它XML文档。

平台及工具:
  • windows7 旗舰版
  • VS2008
问题:

当生成的XPath字符串包含两个字符属性条件时出现异常“具有无效标记”。

 根据提供的元素属性名称数组及其对应的值数组合成XPath字符串,然后使用XPathSelectElements函数查询所有满足条件的元素集合,以下面的简单用户信息XML文档为例:

<?xml version="1.0" encoding="utf-8"?>
 <Users>
      <User ID="U001" UserName="Jack" age="20" DeptID="D001"  />
      <User ID="U002" UserName="Tom" age="22" DepatID="D002" />
      <User ID="U003" UserName="Jerry" age="25" DepatID="D002" />
  </Users>
    
通过以下函数查询出满足条件的元素集合:
 
/// <summary>
/// 根据指定属性和值条件查找元素
/// </summary>
/// <param name="columns">元素属性名称数组</param>
/// <param name="values">元素属性对应的值数组</param>
/// <returns></returns>
public List<XElement> FindElements(string[] columns, string[] values)
{
    if (columns.Count() != values.Count())
    {
       throw new Exception("条件字段数目和值数目不匹配,无法生成查询条件!");
    }
    //循环逐个查找到满足条件的元素
    StringBuilder xpath = new StringBuilder(xTableName + "[");
    for (short index = 0; index < columns.Count(); index++)
    {
        //增加and逻辑运算符
         if (index > 0)
        {
            xpath.Append(" AND");
        }
        xpath.Append(columns[index]);
        xpath.Append("=");
        xpath.Append("'" + values[index] + "'");
    }
    xpath.Append("]");
    //根据xpath进行查询
     return xmlDB.XPathSelectElements(xpath.ToString());
}

如果是单个属性作为条件,能够正确找到需要的元素;如果为多个元素属性作为条件,而且其中包含多个字符串类型条件将产生具有无效标记的异常,跟踪xpath.ToString()生成的查询条件及其结果为:

XPath字符串结果
User[@ID='U001']成功
User[@ID='U001' AND @Age=20]成功
User[@Age=20]成功
User[@Age>20]成功
User[@ID='U001' AND @UserName='Jack']异常
User[@ID='' AND @UserName='']异常
User[@ID=\"U001\" AND @UserName=\"Jack\"]异常
User[@ID=\'U001\' AND @UserName=\'Jack\']异常
@"User[@ID=\'U001\' AND @UserName=\'Jack\']"异常

为达到同样的目的只能采用折衷方式,根据提供的元素属性条件逐个提取满足条件的元素,如果数据量太大将会影响性能:

 

public List<XElement> FindElements(string[] columns, string[] values)
        {
            List<XElement> nodes = null,filterNodes = null;            
            if (columns.Count() != values.Count())
            {
                throw new Exception("条件字段数目和值数目不匹配,无法生成查询条件!");
            }
            //循环逐个查找到满足条件的元素
             for (short index = 0; index < columns.Count(); index++)
            {
                string value = values[index];
                string atrrName = columns[index];               
                //初始化列表
                if (index == 0)
                {
                    IEnumerable<XElement> elements = xmlTable.XPathSelectElements(xTableName + "[@" + columns[index] + "='" + value + "']");
                    if (elements == null || elements.Count<XElement>() == 0)
                        return null;
                    else
                    {
                        nodes = elements.ToList<XElement>();
                        elements = null;
                        continue;
                    }
                }
                if (nodes == null)
                {
                    return null;
                }
                //按条件过滤数据
                 var data = from e in nodes
                           where e.Attribute(atrrName).Value ==  value
                           select e;
                 filterNodes = data.ToList<XElement>();
                if (filterNodes == null || filterNodes.Count<XElement>() == 0)
                    return null;

                nodes = filterNodes;
            }
           //根据xpath进行查询
            if(nodes==null || nodes.Count<XElement>() == 0)
          {
              return null;
          }
          else
          {
             return nodes;//.First<XElement>();
          }
                    
        }


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值