最近项目[Silverlight]中的需要实现国际化,需要对所有控件进行一个处理。由于使用了Telerik的控件,只需要去掉原有的Label或者Header属性,然后添加一个资源Key即可。但是在项目已经完全成熟的情况下,对大量的查询条件,数据列进行处理也是一个非常耗时的方案,因此对XAML文件进行处理能够节省大量的工作量,避免错误信息。

关键的步骤可以通过VS的向导自动完成。接下来只需在Conect.cs文件中对部分数据进行处理。

    /// <summary>实现 IDTCommandTarget 接口的 Exec 方法。此方法在调用该命令时调用。</summary>
/// <param term='commandName'>要执行的命令的名称。</param>
/// <param term='executeOption'>描述该命令应如何运行。</param>
/// <param term='varIn'>从调用方传递到命令处理程序的参数。</param>
/// <param term='varOut'>从命令处理程序传递到调用方的参数。</param>
/// <param term='handled'>通知调用方此命令是否已被处理。</param>
/// <seealso class='Exec' />
public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
handled = false;
if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if (_applicationObject.ActiveDocument == null)
return;
// 获取当前画面名称
string pageName = _applicationObject.ActiveDocument.Name;
pageName = pageName.Substring(, pageName.IndexOf(".")); TextDocument doc = _applicationObject.ActiveDocument.Object() as TextDocument;
if (commandName == "Aladdin.Connect.Aladdin")
{
try
{
// 获取当前的内容,并进行替换
var startPoint = doc.CreateEditPoint(doc.StartPoint);
var text = startPoint.GetText(doc.EndPoint);
string newContent = I18nHelper.DoReplace(pageName, text);
// 先删除
startPoint.Delete(doc.EndPoint);
// 重新写入
startPoint.Insert(newContent); handled = true;
return;
}
catch (Exception ex)
{
MessageBox.Show("格式化错误。" + ex.Message);
}
}
}
}

主要代码就是通过获取当前的TextDocument进行处理。

在编辑器文档中中获取一段内容的方法就是定义一个起始位置,然后从起始位置开始通过GetText获取到指定结束位置。

然后通过Delete和Insert进行处理。

NOTE:之前尝试了使用SelectionText进行处理,发现替换效率比较慢,应该是SelectionText这个对象是内容更新时一直在变化的原因。

对文本进行分析有多种办法,比如正则表达式、字符串查找替换等,这里由于处理的是XAML,因此使用了XML的处理方式。

在分析之前有几点需要注意的地方:

  • XAML是带有命名空间的,需要预先分析命名空间,并在带有命名空间的SelectNodes等地方使用;
  • 在添加(或者修改,此处有待确认)节点或者属性时,需要注意
  • XML内容在输出为字符串,并将内容传给编辑器时,需要使用XmlWriterSettings进行处理缩进等问题。
        public static string DoReplace(string pageName, string content)
{
if (String.IsNullOrEmpty(content)) return content; XmlDocument doc = new XmlDocument();
doc.LoadXml(content); XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);
var docRoot = doc.FirstChild; // 根据根节点信息,获取命名空间列表
foreach (var ns in GetNamespaces(docRoot))
nsManager.AddNamespace(ns.Key, ns.Value); // 遍历所有子节点,进行处理
foreach (XmlNode root in docRoot.ChildNodes)
{
Process(doc, root, pageName, nsManager);
} // 数据输出,格式设定
StringBuilder strBuilder = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.NewLineHandling = NewLineHandling.Replace;
settings.OmitXmlDeclaration = true;
settings.ConformanceLevel = ConformanceLevel.Fragment; XmlWriter writer = XmlWriter.Create(strBuilder, settings);
doc.WriteTo(writer);
writer.Flush();
writer.Close(); // 替换根节点内容
string newRootAttributes = ReplaceHelper.ProcessRoot(docRoot);
string newContent = strBuilder.ToString(); string newRawAttributes = newContent.Substring(, newContent.IndexOf(">"));
return newContent.Replace(newRawAttributes, newRootAttributes);
} private static void Process(XmlDocument doc, XmlNode root, string pageName, XmlNamespaceManager nsManager)
{
// TODO:节点处理和递归
}

简单的添加属性的方法类似于,即必须制定其NamespaceURI,否则会自动在结点后添加命名空间属性:

 foreach (XmlNode field in root.SelectNodes("EF:EFDataFieldGroup.DataFields", nsManager))
{
if (field.Attributes == null) continue; if (field.Attributes["EF:I18nManager.ResourceKey"] == null)
{
string fieldValue = field.OuterXml;
// 数据进行处理
var startIdx = fieldValue.IndexOf("inqu_status-0-");
var endIdx = fieldValue.IndexOf("\"", startIdx); if (startIdx + >= endIdx) continue; string itemId = fieldValue.Substring(startIdx + , endIdx - startIdx - );
string bindingName = string.Format("{0}U_DATAFIELD_{1}", pageName, itemId); //XmlAttribute attr = doc.CreateAttribute("EF:I18nManager.ResourceKey", bindingName);
//field.Attributes.Append(attr); //XmlElement element = field as XmlElement;
var attr = doc.CreateAttribute("EF:I18nManager.ResourceKey", field.NamespaceURI);
attr.Value = bindingName;
field.Attributes.Append(attr); // 同时删除原有的标签
var labelAttr = field.Attributes["eLabel"];
if (null != labelAttr)
field.Attributes.Remove(labelAttr);
//element.SetAttribute("EF:I18nManager.ResourceKey",field.NamespaceURI, bindingName);
}
}

分析XAML文档的命名空间列表的简单实现如下:

        private static IDictionary<string, string> GetNamespaces(XmlNode root)
{
IDictionary<string, string> dicNS = new Dictionary<string, string>(); // 获取第一个节点中的所有 foreach (XmlNode node in root.Attributes)
{
var item = node.OuterXml; if (item.IndexOf("xmlns") > -)
{
int nameStart = item.IndexOf(":");
int nameEnd = item.IndexOf("=");
if (nameStart >= nameEnd) continue; string key = item.Substring(nameStart + , nameEnd - nameStart - ).Trim(); if (String.IsNullOrEmpty(key)) continue; int contentStart = item.IndexOf("\"", nameEnd);
int contentEnd = item.IndexOf("\"", contentStart + );
string val = item.Substring(contentStart + , contentEnd - - contentStart); dicNS.Add(key, val);
}
} return dicNS;
}
}

【Visual Studio2010】创建XAML分析插件的更多相关文章

  1. Xamarin XAML语言教程使用Visual Studio创建XAML

    Xamarin XAML语言教程使用Visual Studio创建XAML Xamarin.Forms允许开发人员通过XAML语法对程序的所有用户界面元素进行详细的定制,如文本.按钮.图像和列表框等. ...

  2. Xamarin XAML语言教程使用Xamarin Studio创建XAML(二)

    Xamarin XAML语言教程使用Xamarin Studio创建XAML(二) 使用Xamarin Studio创建XAML Xamarin Studio和Visual Studio创建XAML文 ...

  3. Visual Studio 2017创建XAML文件

    Visual Studio 2017创建XAML文件   在Visual Stuido 2015中,在已经创建好的项目中添加XAML文件,只要右击项目,单击“添加”|“新建项”命令,然后从“添加新项” ...

  4. 11个Visual Studio代码性能分析工具

    软件开发中的性能优化对程序员来说是一个非常重要的问题.一个小问题可能成为一个大的系统的瓶颈.但是对于程序员来说,通过自身去优化代码是十分困难的.幸运的是,有一些非常棒的工具可以帮助程序员进行代码分析和 ...

  5. 【转】怎样创建一个Xcode插件(Part 1)

      原文:How To Create an Xcode Plugin: Part 1/3 原作者:Derek Selander 译者:@yohunl 译者注:原文使用的是xcode6.3.2,我翻译的 ...

  6. Visual Studio2015 Community一些必备插件

    Visual Studio2015 Community一些必备插件 是不是感觉虽然VS2015的代码编辑能力已经很强大了,但是总感觉差了那么一些呢?不用担心,它有很多非常强大的插件,能够让你打代码事半 ...

  7. MyBatis 源码分析 - 插件机制

    1.简介 一般情况下,开源框架都会提供插件或其他形式的拓展点,供开发者自行拓展.这样的好处是显而易见的,一是增加了框架的灵活性.二是开发者可以结合实际需求,对框架进行拓展,使其能够更好的工作.以 My ...

  8. .NET 11 个 Visual Studio 代码性能分析工具

    原文地址 软件开发中的性能优化对程序员来说是一个非常重要的问题.一个小问题可能成为一个大的系统的瓶颈.但是对于程序员来说,通过自身去优化代码是十分困难的.幸运的是,有一些非常棒的工具可以帮助程序员进行 ...

  9. mapbox-gl空间分析插件turf.js使用介绍

    mapbox-gl能够方便地显示地图,做一些交互,但是缺少空间分析功能,比如绘制缓冲区.判断点和面相交等等. turf.js是一个丰富的用于浏览器和node.js空间分析库,官网 http://tur ...

随机推荐

  1. 基于Linux的oracle数据库管理 part1( 准备及linux基础 )

    主要内容 1. 安装VMware tools (好处, 显示效果增强, 从虚拟机出来不需要alt+ctrl 切换) 2. Linux 启动过程, 方便以后oracle 自动启动与关闭 3. Linux ...

  2. window-messager(消息框)

    所有的消息框都是异步的.用户可以在交互消息之后使用回调函数去处理结果或做一些自己需要处理的事情. 一.alert(警告框) <script type="text/javascript& ...

  3. 【笨嘴拙舌WINDOWS】字符类型与字符串

    "我将用C语言作为工具,开始WINDOWS API的使用" windows NT 从底层开始支持unicode. 1.字符类型 WINDOWS的字符类型在WINNT.H和CTYPE ...

  4. Qt之国际化(系统文本-QMessageBox按钮、QLineEdit右键菜单等)

    简介 使用Qt的时候,经常会遇到英文问题,例如:QMessageBox中的按钮.QLineEdit.QSpinBox.QScrollBar中的右键菜单等.通常情况下,我们软件都不会是纯英文的,那么如何 ...

  5. HDU 1372 (搜索方向稍有改变) Knight Moves

    其实手写模拟一个队列也挺简单的,尤其是熟练以后. 尼玛,这题欺负我不懂国际象棋,后来百度了下,国际象棋里骑士的走法就是中国象棋里面的马 所以搜索就有八个方向 对了注意初始化标记数组的时候,不要把起点标 ...

  6. JDK,JRE,JVM区别与联系-理解与概括

    我们利用JDK(调用JAVA API)开发了属于我们自己的JAVA程序后,通过JDK中的编译程序(javac)将我们的文本java文件编译成JAVA字节码,在JRE上运行这些JAVA字节码,JVM解析 ...

  7. 信息熵 Information Theory

    信息论(Information Theory)是概率论与数理统计的一个分枝.用于信息处理.信息熵.通信系统.数据传输.率失真理论.密码学.信噪比.数据压缩和相关课题.本文主要罗列一些基于熵的概念及其意 ...

  8. 【转】iOS开发UI篇—iPad和iPhone开发的比较

    原文网址:http://www.cnblogs.com/wendingding/p/3918007.html iOS开发UI篇—iPad和iPhone开发的比较 一.iPad简介 1.什么是iPad ...

  9. APP打包上线应注意的问题!

    咱们只谈技术不谈业务!关系到怎么推广怎么让软件发扬光大,其实归根结底这都和公司的现状和产品经理有直接的联系,与我们程序员关系不太密切.   我总结的上线项目和我做的项目以及公司外包过来的项目升级再次发 ...

  10. AJax学习一

    1.Ajax的准备工作,就是要先准备好服务器环境. 这边可以有好几种方式,例如服务器工具: http://www.php100.com/html/plugin/ser/2013/0905/91.htm ...