LinqToXml高级用法介绍

时间:2022-09-11 22:03:26

LinqToXml高级用法介绍

一、函数构造

什么是函数构造?其是指通过单个语句构建XML树的能力。

那么它有什么作用呢?

作用1、用单个表达式快速创建复杂的XML树

见实例代码CreateXml( ):

LinqToXml高级用法介绍
public static XElement CreateXml()
{
XElement emp = new XElement("Employees",
new XElement("Employee",new XAttribute("id","1"),
new XAttribute("Dept","00001"),
new XElement("name","Scott"),
new XElement("Address",
new XElement("Street","555 main st."),
new XElement("City","Wellington"),
new XElement("State","FL"),
new XElement("Zip","33144")
),
new XElement("Title","All things Techy"),
new XElement("HireDate","02/05/2007"),
new XElement("Gender","M")
)
);
return emp;
}
LinqToXml高级用法介绍

输出结果:

LinqToXml高级用法介绍
<Employees>
<Employee id="1" Dept="00001">
<name>Scott</name>
<Address>
<Street>555 main st.</Street>
<City>Wellington</City>
<State>FL</State>
<Zip>33144</Zip>
</Address>
<Title>All things Techy</Title>
<HireDate>02/05/2007</HireDate>
<Gender>M</Gender>
</Employee>
</Employees>
LinqToXml高级用法介绍

作用2、通过查询表达式容易地控制所构建的XML树,更方便的修改和保存XML树。

见实例代码EditXml( )

LinqToXml高级用法介绍
public static XElement EditXml()
{
XElement emp = XElement.Load(@"output.xml");
emp = new XElement("Employee",
emp.Element("Employee").Element("name"),
from atts in emp.Element("Employee").Attributes() where atts.Name == "id" select new XElement(atts.Name, (string)atts)
);
return emp;
}
LinqToXml高级用法介绍

输出结果:

<Employee>
<name>Scott</name>
<id>1</id>
</Employee>

二、批注

什么是批注?

批注是与一段文本相关联的说明性的注释。但批注是不可见的

实例代码AddAnnotation( ):

LinqToXml高级用法介绍
public static XElement AddAnnotation()
{
_2Annotation anno = new _2Annotation(5);
XElement root = XElement.Load("output.xml");
root.AddAnnotation(anno);
root.AddAnnotation("批注:1");
root.AddAnnotation("批注:2");
//批注不可见,但可通过下面这种方式获取批注值
_2Annotation newAnno = root.Annotation<_2Annotation>();
Console.WriteLine("批注值:" + newAnno.Val1);
IEnumerable<string> stringList = root.Annotations<string>();
foreach (string item in stringList)
{
Console.WriteLine(item);
} return root;
}
LinqToXml高级用法介绍

输出结果:

批注值:5
批注:1
批注:2

三、轴

Linq To Xml轴是干什么用的?

在一个xml数中遍历并返回多个节点的值。其返回元素和属性的集合。

轴的实现方法有哪些呢

方法1:Ancestors

其返回指定节点的上级元素的集合

见代码Ancestors():

LinqToXml高级用法介绍
private XElement _XmlE;
public _3Zhou()
{
_XmlE = new XElement("Employees",
new XElement("Employee",
new XElement("Name",
new XElement("FirstName", "Gong"),
new XElement("MiddleName", "Wen"),
new XElement("LastName", "Tao")
),
new XElement("Sex", "男")
),
new XElement("Employee",
new XElement("Name",
new XElement("FirstName", "Zhao"),
new XElement("MiddleName", "Si"),
new XElement("LastName", "Si")
),
new XElement("Sex", "Girl")
)
);
}
public IEnumerable<XElement> Ancestors()
{
return _XmlE.Elements("Employee").Elements("Name").Ancestors<XElement>();
}
LinqToXml高级用法介绍

见输出:

LinqToXml高级用法介绍

同时它还包含一个重载方法,即Ancestors(XName name), name是使集合只返回指定name的元素。

见代码Ancestors(string xname):

LinqToXml高级用法介绍
public IEnumerable<XElement> Ancestors(string xname)
{
return _XmlE.Elements("Employee").Elements("Name").Ancestors<XElement>(xname);
}
LinqToXml高级用法介绍

见输出:

LinqToXml高级用法介绍

方法2:Descendants

与Ancestors方法相反,其返回指定元素的后续元素的集合

见代码:

public IEnumerable<XElement> Descendants()
{
return _XmlE.Elements("Employee").Elements("Name").Descendants<XElement>();
}

见输出:

LinqToXml高级用法介绍

它同时也包含一个重载方法Descendants(string xname),作用和Ancestors方法一样

方法3:AncestorsAndSelf

方法4:DescendantsAndSelf

方法3和方法4同方法1和2,不过返回的集合中包含了自身元素而已。

四、事件

事件是指,当你对xml树进行修改时,linq to xml事件会提供通知。主要包含两个事件,一个是changing一个是changed,changing就是在改变之前触发,changed是改变之后触发。但如果是修改值得话,会触发两遍,因为这是一次删除和一次插入的操作。

见代码:

LinqToXml高级用法介绍
public _4Event()
{
_XmlE = new XElement("Employees",
new XElement("Employee",
new XElement("Name",
new XElement("FirstName", "Gong"),
new XElement("MiddleName", "Wen"),
new XElement("LastName", "Tao")
),
new XElement("Sex", "男")
),
new XElement("Employee",
new XElement("Name",
new XElement("FirstName", "Zhao"),
new XElement("MiddleName", "Si"),
new XElement("LastName", "Si")
),
new XElement("Sex", "Girl")
)
);
_XmlE.Changing += _XmlE_Changing;
_XmlE.Changed += _XmlE_Changed;
_XmlE.Element("Employee").Elements("Name").Elements("FirstName").First().AddAfterSelf(new XElement("NickName", "taoGe"));
} void _XmlE_Changed(object sender, XObjectChangeEventArgs e)
{
Console.WriteLine("changed event raised");
XElement newEl = (XElement)sender;
Console.WriteLine("Sender:" + newEl.Name);
Console.WriteLine("Object Change:" + e.ObjectChange);
} void _XmlE_Changing(object sender, XObjectChangeEventArgs e)
{
// throw new NotImplementedException();
Console.WriteLine("changing event raised");
XElement newEl = (XElement)sender;
Console.WriteLine("Sender:" + newEl.Name);
Console.WriteLine("Object Change:" + e.ObjectChange);
}
LinqToXml高级用法介绍

见输出:

LinqToXml高级用法介绍

五、流处理Xml文档

这个主要用于处理大型xml文档和树的。因为大型xml文档会非常消耗内存。而流处理的工作原理是从xml源中读取一小片段数据,进行处理,从而减少内存的使用量。

其具体实现是使用XmlReader类来快速遍历XML文档以寻找所需要的节点,然后调用ReadFrom方法从源读取信息并填充到目标xml片段。

见代码:

LinqToXml高级用法介绍
public static IEnumerable<XElement> StreamSalesOrders(string uri)
{
using (XmlReader reader = XmlReader.Create(uri))
{
XElement name = null;
XElement order = null;
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "SalesPerson")
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "Name")
{
name = XElement.ReadFrom(reader) as XElement;
break;
}
}
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.EndElement)
{
break;
}
if (reader.NodeType == XmlNodeType.Element && reader.Name == "Order")
{
order = XElement.ReadFrom(reader) as XElement;
if (order != null)
{
XElement tmpRoot = new XElement("TempRoot", new XElement(name));
tmpRoot.Add(order);
// yield return 提供了迭代器一个比较重要的功能,
//即取到一个数据后马上返回该数据,不需要全部数据装入数列完毕,这样有效提高了遍历效率。
yield return order;
}
}
}
}
}
}
}
LinqToXml高级用法介绍

见输出:

LinqToXml高级用法介绍

源码下载:

喜欢就动动手指点下推荐吧,您的支持是我分享的动力!

分贝显示器,实时显示声音强度

使用 摄像头、麦克风、扬声器测试程序 一文中提到的技术,我们可以基本实现QQ的语音视频测试向导的功能了。但是,我觉得语音测试这块的体验还可以做得更好一点,就像QQ语音测试一样,实时显示麦克风采集到的声音的强度:

LinqToXml高级用法介绍

接下来,我们做个小demo,来实现类似的功能。先上demo运行起来的截图:

LinqToXml高级用法介绍

(界面确实比较丑,我们这里的重点在于技术方面如何实现,如果你愿意花点时间,可以将其美化得跟QQ的那个一样漂亮^_^)

1.实现思路

实现这个小例子的主要思路如下:

(1)使用OMCS采集和播放从麦克风的输入数据(PCM)。

(2)对采集到的数据进行傅立叶变换,变换的结果就可以反应声音的强度。

(3)使用ProgressBar控件来实时显示声音的强度信息。

2.具体实现

(1)傅立叶变换算法

LinqToXml高级用法介绍
    public static class FourierTransformer
{
public static double[] FFTDb(double[] source)
{
int sourceLen = source.Length;
int nu = (int)(Math.Log(sourceLen) / Math.Log(2));
int halfSourceLen = sourceLen / 2;
int nu1 = nu - 1;
double[] xre = new double[sourceLen];
double[] xim = new double[sourceLen];
double[] decibel = new double[halfSourceLen];
double tr, ti, p, arg, c, s;
for (int i = 0; i < sourceLen; i++)
{
xre[i] = source[i];
xim[i] = 0.0f;
}
int k = 0;
for (int l = 1; l <= nu; l++)
{
while (k < sourceLen)
{
for (int i = 1; i <= halfSourceLen; i++)
{
p = BitReverse(k >> nu1, nu);
arg = 2 * (double)Math.PI * p / sourceLen;
c = (double)Math.Cos(arg);
s = (double)Math.Sin(arg);
tr = xre[k + halfSourceLen] * c + xim[k + halfSourceLen] * s;
ti = xim[k + halfSourceLen] * c - xre[k + halfSourceLen] * s;
xre[k + halfSourceLen] = xre[k] - tr;
xim[k + halfSourceLen] = xim[k] - ti;
xre[k] += tr;
xim[k] += ti;
k++;
}
k += halfSourceLen;
}
k = 0;
nu1--;
halfSourceLen = halfSourceLen / 2;
}
k = 0;
int r;
while (k < sourceLen)
{
r = BitReverse(k, nu);
if (r > k)
{
tr = xre[k];
ti = xim[k];
xre[k] = xre[r];
xim[k] = xim[r];
xre[r] = tr;
xim[r] = ti;
}
k++;
}
for (int i = 0; i < sourceLen / 2; i++)
{
decibel[i] = 10.0 * Math.Log10((float)(Math.Sqrt((xre[i] * xre[i]) + (xim[i] * xim[i]))));
} return decibel;
} private static int BitReverse(int j, int nu)
{
int j2;
int j1 = j;
int k = 0;
for (int i = 1; i <= nu; i++)
{
j2 = j1 / 2;
k = 2 * k + j1 - 2 * j2;
j1 = j2;
}
return k;
}
}
LinqToXml高级用法介绍

至于傅立叶变换与分贝有什么关系,网上有很多相关的资料,可以baidu一下。对有兴趣的童鞋,强烈推荐阅读这篇文章 -- 分贝是个什么东西?

(2)初始化OMCS服务器、设备管理器、麦克风设备

LinqToXml高级用法介绍
        //获取麦克风列表
IList<MicrophoneInformation> microphones = SoundDevice.GetMicrophones();
this.comboBox2.DataSource = microphones;
if (microphones.Count > 0)
{
this.comboBox2.SelectedIndex = 0;
} //初始化OMCS服务器
OMCSConfiguration configuration = new OMCSConfiguration(10, 1, EncodingQuality.High, 16000, 800, 600);
this.multimediaServer = new MultimediaServer(9000, new DefaultUserVerifier(), configuration, false, null); this.multimediaManager.DeviceErrorOccurred += new CbGeneric<MultimediaDeviceType, string>(multimediaManager_DeviceErrorOccurred);
this.multimediaManager.AudioCaptured += new CbGeneric<byte[]>(multimediaManager_AudioCaptured);
this.microphoneConnector1.ConnectEnded += new CbGeneric<ConnectResult>(microphoneConnector1_ConnectEnded);
LinqToXml高级用法介绍

(3)连接麦克风,开始采集

LinqToXml高级用法介绍
    if (!SoundDevice.IsSoundCardInstalled())
{
this.label_error.Visible = true;
this.label_error.Text = "声卡没有安装";
} //初始化多媒体管理器
this.multimediaManager.MicrophoneDeviceIndex = this.comboBox2.SelectedIndex;
this.multimediaManager.Initialize("tester", "", "127.0.0.1", 9000); //与OMCS服务器建立连接,并登录 //尝试连接麦克风
this.microphoneConnector1.BeginConnect("tester");
LinqToXml高级用法介绍

首先,初始化本地多媒体设备管理器,然后使用麦克风连接器连接到当前登录用户“tester”(即“自己”)麦克风设备。如果连接成功,多媒体管理器将会触发AudioCaptured事件,我们通过这个事件来截获音频数据。

(4)处理采集到的音频数据,并显示结果

LinqToXml高级用法介绍
        void multimediaManager_AudioCaptured(byte[] data)
{
double[] wave = new double[data.Length / 2];
int h = 0;
for (int i = 0; i < wave.Length; i += 2)
{
wave[h] = (double)BitConverter.ToInt16(data, i); //采样位数为16bit
++h;
} double[] res = FourierTransformer.FFTDb(wave); double kk = 0;
foreach (double dd in res)
{
kk += dd;
}
if (kk < 0)
{
kk = 0;
}
this.showResult(kk / res.Length);
} private void showResult(double rs)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new CbGeneric<double>(this.showResult), rs);
}
else
{
int rss = (int)(rs * 2);
if (rss < 40)
{
rss = 40;
}
if (rss > 100)
{
rss = 100;
} this.progressBar1.Value = rss;
}
}
LinqToXml高级用法介绍

注意:由于OMCS音频采样的位数为16bit,这样,一个单位的语音样本的字节数为2个字节。所以,傅立叶变换前,先要将原始的PCM数据(byte[])转为Int16的数组。

在显示分贝强度时,我偷了下懒,直接使用了ProgressBar控件,体验不是很好,勉强能表达出意思吧。

3.Demo程序

源码下载

 
 
分类: C#专栏

LinqToXml高级用法介绍的更多相关文章

  1. Jenkins高级用法 - Jenkinsfile 介绍及实战经验

    系列目录 1.Jenkins 安装 2.Jenkins 集群 3.Jenkins 持续集成 - ASP.NET Core 持续集成(Docker&*风格&Jenkinsfile) 4 ...

  2. Visual Studio 宏的高级用法

    因为自 Visual Studio 2012 开始,微软已经取消了对宏的支持,所以本篇文章所述内容只适用于 Visual Studio 2010 或更早期版本的 VS. 在上一篇中,我已经介绍了如何编 ...

  3. sqlalchemy&lpar;二&rpar;高级用法

    sqlalchemy(二)高级用法 本文将介绍sqlalchemy的高级用法. 外键以及relationship 首先创建数据库,在这里一个user对应多个address,因此需要在address上增 ...

  4. Solr学习总结(六)SolrNet的高级用法(复杂查询,分页,高亮,Facet查询)

    上一篇,讲到了SolrNet的基本用法及CURD,这个算是SolrNet 的入门知识介绍吧,昨天写完之后,有朋友评论说,这些感觉都被写烂了.没错,这些基本的用法,在网上百度,资料肯定一大堆,有一些写的 ...

  5. Newtonsoft&period;Json高级用法&lpar;转&rpar;

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

  6. 【转】 Newtonsoft&period;Json高级用法

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

  7. Newtonsoft&period;Json高级用法 1&period;忽略某些属性 2&period;默认值的处理 3&period;空值的处理 4&period;支持非公共成员 5&period;日期处理 6&period;自定义序列化的字段名称

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

  8. Android(java)学习笔记264:Android下的属性动画高级用法(Property Animation)

    1. 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了.但是,正如上篇文章当中所说到的,属性动画对补间动画 ...

  9. 细说 ASP&period;NET Cache 及其高级用法

    许多做过程序性能优化的人,或者关注过程程序性能的人,应该都使用过各类缓存技术. 而我今天所说的Cache是专指ASP.NET的Cache,我们可以使用HttpRuntime.Cache访问到的那个Ca ...

随机推荐

  1. vijos1531 食物链

    背景 安徽省芜湖市第二十七中学测试题 NOI 2001 食物链(eat) Description:OfficialData:OfficialProgram:JackDavid127 描述 动物王国中有 ...

  2. gcd推导

    欧几里得算法有性质: gcd(a, b)=gcd(b, a%b); 那么如何证明呢~ 法1: 我们先假设其成立并且有 gcd(a, b)=gcd(b, a%b)=d; a=k*b+c即a%b=c(我们 ...

  3. 修改了chrome的官方的有道词典插件,添加了生词本的功能

    项目地址+导入教程 https://github.com/cclient/chrome-extensions-youdaowithwordnode

  4. &lbrack;Design Pattern&rsqb; Substitute Interface

    [Design Pattern] Substitute Interface 目的 将对象的成员建立为替身接口的成员,用来解耦对象之间的循环相依. 情景 假设开发人员接手一个系统,在系统里有订单对象.送 ...

  5. 迅为4412开发板Linux驱动教程之GPIO的初始化

    视频下载地址:http://pan.baidu.com/s/1c06oiti GPIO的初始化 • 在内核源码目录下使用命令“ls drivers/gpio/*.o”,可以看到“gpio-exynos ...

  6. sql server日期时间函数

    From:http://www.cnblogs.com/linzheng/archive/2010/11/17/1880208.html 1.  当前系统日期.时间  select getdate() ...

  7. ADO&period;NET之使用DataGridView控件显示从服务器上获取的数据

    今天回顾下ADO.NET中关于使用DataGridiew控件显示数据的相关知识 理论整理: 使用 DataGridView 控件,可以显示和编辑来自多种不同类型的数据源的表格数据. SqlDataAd ...

  8. BEGINNING SHAREPOINT&amp&semi;&num;174&semi; 2013 DEVELOPMENT 第15章节--开发SP2013工作流应用程序 总结

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第15章节--开发SP2013工作流应用程序 总结         在SP2013中,工作流已经从SP Server中脱离 ...

  9. DOM-基本概念及使用

    1.获取元素的方式总结 1.根据 id 的属性的值获取元素,返回值是一个元素对象 document.getElementById("id属性的值"); 2.根据标签名获取元素,返回 ...

  10. tmux 没有默认配置文件。

        解决: 1.复制粘贴一个(有例子),然后关闭tmux server. tmux kill-server.重新启动生效. 2.复制粘贴一个,然后sourece一下: tmux source ~/ ...