阅读我认为的 OP:能够关联到 Visual Studio 项目中的任何 xml 文件不是很好吗 - 一个用于转换此文件的 XSL 文件。此转换的结果将显示为原始 xml 文件下的子项,例如 *.xaml.cs 出现在 *.xaml 下。我们将能够通过 Properties 将任何 Build Action 分配给这个新的 xml 文件。
现在这是不可能的,但存在另一种更通用的预处理技术 - T4。以下是如何使用它将“我们的”xml 片段插入“他们的”生成的 xml 文件的描述。
1) 假设“他们”生成的 xml 文件包含在我们的项目中,名称为 aaa.xml。
例如aaa.xml:
<?xml version="1.0" encoding="utf-8"?>
<abc>
<data a="1"/>
<data a="2"/>
<placeholderForTranslations/>
<data>ccc</data>
</abc>
其中 placeholderForTranslations 元素需要替换为“我们的”片段。
2) 让我们将 aaa.xslt 文件添加到我们的项目中,该文件通过将 placeholderForTranslations 替换为“我们的”片段来转换 aaa.xml。
aaa.xslt:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="placeholderForTranslations">
<translations>
<trans orig="aaa" translated="AAA"/>
</translations>
</xsl:template>
</xsl:stylesheet>
这里的第一个 xsl:template 表示默认情况下,转换引擎会遍历输入文件的节点,它只是将它们原样复制到输出中。第二个模板表示,如果遇到 placeholderForTranslations 元素,嵌入到模板中的 xml 片段将用于替换 placeholderForTranslations 元素。事实上,如果您愿意,可以修改 *.tt 文件(见下文),以便也可以从单独的文件中读取此片段。
3) 让我们将 aaa1.tt - t4 代码预处理器文件添加到我们的项目中。
aaa1.tt:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".xml" #>
<#@ assembly name="System.Xml" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Xml.Xsl" #>
<#
string origXmlPath = Host.ResolvePath("aaa.xml");
string transformPath = Host.ResolvePath("aaa.xslt");
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load(transformPath);
MemoryStream stream = new MemoryStream();
transform.Transform(origXmlPath, null, stream);
byte[] generated = stream.ToArray();
string generatedString = Encoding.UTF8.GetString(generated);
#>
<#= generatedString #>
在 <# 和 #> 之间,您可以看到一段 C# 代码,它找到 aaa.xml 和 aaa.xslt 的完整路径,然后将 aaa.xslt 转换应用于 aaa.xml 文件并将结果放入 generatedString 变量中。然后在 <#= generatedString #> 的帮助下,将 generatedString 的内容插入到输出文件中。
如果执行这些步骤,在 Visual Studio 中首次保存 aaa1.tt 时,文件 aaa1.xml 将创建为 aaa1.tt 的子项。您可以通过其属性为该文件分配构建操作,例如“嵌入式资源”。您也可以随时通过右键单击 aaa.tt 并选择“运行自定义工具”来强制重新生成 aaa1.xml。当您构建解决方案时,它也总是会重新生成。
我认为这种方法的优点是您的合并文件是在编译时生成的 - 而不是在应用程序运行时生成的。因此可以在开发过程中目视检查文件。