从Xml模板生成类以构建XPath

时间:2016-04-08 18:43:01

标签: c# .net xml xpath t4

我想知道是否已经有一些东西从XML模板生成一些c#类,以便能够使用xpath创建一个不那么脆弱的代码?

而不是让XPATH Cat.Noeud.Key从生成的类try/catch构建xpath

我在asp.net mvc中使用类似控制器的东西,好奇是否有人在xml模板中使用类似的东西?

[编辑]

我的问题有T4标签,但我没有详细说明,目的是在每次重新编译后重新生成一个T4.tt,以便我们在xml模板中有一个更改,我们将有编译错误

2 个答案:

答案 0 :(得分:1)

如果您正在寻找从XML定义生成类,请查看名为xsd.exe(link)的工具。

如果已定义表示XML的Xml架构(.xsd文件,link here),则xsd.exe可用于生成与该XML架构匹配的类。

一个这样的类的实例将在序列化(作为XML)时生成该实例的XML表示。 (符合生成类时使用的XML模式)。

答案 1 :(得分:0)

像Geekiod提到的那样我使用XSD。这是我的T4设置:

我的T4解决方案中有MyObject.xml文件。

从MyObject.xml生成MyObject.cs(或者当我更改MyObject.xml模式时更新)我运行这个bat脚本:

cd C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin
xsd "C:\Users\XXXX\Documents\Visual Studio 2012\Projects\XXXXX.Templates\XXXXX.Templates.CodeGenerator\MyObject.xml"
xsd "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\MyObject.xsd" /c
xcopy /s "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\MyObject.cs" "C:\Users\XXXXX\Documents\Visual Studio 2012\Projects\XXXXX.Templates\XXXXXX.Templates.Common"

这将运行您的.xml文件上的Microsoft SDK提供的XSD程序。 XSD生成.xsd文件。您在新的.xsd文件上再次运行XSD,它将创建您的.cs文件。都具有相同的名称。然后,该脚本将.cs文件从SDK文件夹复制回我的项目。

现在你有.cs强类型文件,基于你的xml doc。你现在可以在你的.tt文件中做很酷的事情:

<#@ parameter name="XmlFileName" type="System.String" #>
<#

    XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
    StreamReader sr = new StreamReader(this.XmlFileName);
    MyObject O = (MyObject)serializer.Deserialize(sr);

#>
using System;


public class <#= O.Name #> : BusinessObjectBase<<#= O.Name #>Data>
    {
        #region Construction

        private <#= O.Name #>() : base(true) {}

        /// <summary>
        /// Initializes a new instance of the <#= Utility.GetRefClassName(O.Name) #> class.
        /// </summary>
        /// <param name="data"></param>
        <#= Utility.GetRemarksComment2(O) #>
        internal <#= O.Name #>(<#= O.Name #>Data data) : base(data) {}

        #endregion

        #region <#= O.Name #> Data

        <#
        // Generate a property for each child.
        foreach (MyObjectProperty objProp in O.Property)
        {
            if (objProp.GetAccess == "public")
            {
                objProp.GetAccess = ""; 
            }
            else
            {
                objProp.GetAccess = objProp.GetAccess + " ";
            }

            if (objProp.SetAccess == "public")
            {
                objProp.SetAccess = ""; 
            }
            else
            {
                objProp.SetAccess = objProp.SetAccess + " ";
            }

        #>/// <summary>

...

要运行我的T4解决方案以生成.tt文件中的代码,我有&#34; XmlFileName&#34;变量绑定到TextTemplatingSession类。然后,这允许我指向我喜欢的任何MyObject.xml文件(MyOtherObject.xml,Customer.xml等):

static void RunThroughSession()
        {
            string objectName = "MyObject";

            var template = Activator.CreateInstance<BusinessObjectTemplate>();
            TextTemplatingSession session = new TextTemplatingSession();
            session["XmlFileName"] =
                @"C:\Users\XXXXX\Documents\Visual Studio 2012\Projects\XXXXXX.Templates\XXXXXX.Templates.CodeGenerator\" + objectName + ".xml";

            template.Session = session;
            template.Initialize();
            string outputText = template.TransformText();
            using (StreamWriter sr = new StreamWriter(
                @"C:\Users\XXXXX\Documents\Visual Studio 2012\Projects\XXXXX.Templates\XXXXXX.Templates.CodeGenerator\GeneratedCode\BusinessObject" + objectName + ".cs"))
            {
                sr.Write(outputText);
            }

最后一部分是您需要更改&#34;自定义工具&#34;从.tt文件属性到&#34; TextTemplatingFilePreprocessor&#34;的选项。默认值类似于&#34; TextTemplatingGenerator&#34;哪个不适用于此设置。

希望这有帮助!