MSBuild的嵌套属性语法是什么?

4

我正在使用MSBuild。

通过$(Person_1),我可以获取Person_1的值。那么,如何获取Person_2Name子元素的值呢?我需要语法。

<PropertyGroup>
  <Person_1>Bob</Person_1>
  <Person_2>
    <Name>Bob</Name>
  </Person_2>
</PropertyGroup>
3个回答

4

关于: https://msdn.microsoft.com/en-us/library/ms171458.aspx 包含XML的属性就是简单的XML。仅仅因为它是XML,你不能访问其内容的部分。要理解这一点,请执行以下操作:

<PropertyGroup> 
   <MyProperty>
       <PropertyContentXML>
           <InnerXML1>Blablabla</InnerXML1>
           <InnerXML2>More blablabla</InnerXML2>
       </PropertyContentXML>
   </MyProperty>
</PropertyGroup> 
<Target Name="Build">
    <Message Text="$(MyProperty)" />
</Target>

这将会输出:
<PropertyContentXML xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <InnerXML1>Blablabla</InnerXML1>
        <InnerXML2>More blablabla</InnerXML2>
</PropertyContentXML>

1

您正在混淆属性和ItemGroups。

属性是简单的命名值,ItemGroups是具有标识和属性的项。您不能以相同的方式使用两者。

属性定义为:

<PropertyGroup>
    <name>value</name>
</Propertygroup>

这些内容与编程有关,可以使用$(name)语法来访问。

项目组的定义如下:

<ItemGroup>
    <Item Include="item1">
        <ItemPropery>value</ItemProperty>
    </Item>
</ItemGroup>

这些属性可以通过使用以下语法进行访问:%(Item.ItemProperty)

另请参见此参考文献中的“直观”语法


不,我认为你是错的。看这里的“在属性中存储XML”章节:https://msdn.microsoft.com/zh-cn/library/ms171458.aspx - Andrey Bushman
嗯,这仍然是同样的问题,不是吗?您现在将XML值存储在(扁平)属性中,而不是文本值。语法可能会让人困惑,但对于msbuild来说,这仍然是一个具有单个(在此情况下为xml)值的简单属性。请注意,示例明确限制了构建的xml值的使用:“属性可以包含任意XML,这可以帮助传递值到任务或显示日志信息。”它没有说您可以使用msbuild语法读取xml内容。 - oɔɯǝɹ

0

你需要像内联任务这样的高级功能:

<UsingTask TaskName="TransformXmlToItem" 
           TaskFactory="CodeTaskFactory"
           AssemblyName="Microsoft.Build.Tasks.Core">
  <ParameterGroup>
    <Xml Required="true"/>
    <Elements ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true"/>
  </ParameterGroup>
  <Task>
    <Reference Include="System.Xml" />
    <Using Namespace="System.Collections.Generic" />
    <Using Namespace="System.Xml" />
    <Code Type="Fragment" Language="cs">
      <![CDATA[  
        using (var xr = new XmlTextReader(Xml, XmlNodeType.Element,
            new XmlParserContext(null, null, null, XmlSpace.Default))) {

            xr.Namespaces = false;
            xr.MoveToContent();
            var items = new List<ITaskItem>();
            while (!xr.EOF) {
                if (xr.NodeType == XmlNodeType.Element) {
                    var item = new TaskItem(xr.Name);
                    var text = xr.ReadElementContentAsString();
                    if (!string.IsNullOrWhiteSpace(text)) {
                        item.SetMetadata("text", text);
                    }
                }
                xr.Read();
            }
            Elements = items.ToArray();
        }
    ]]>
  </Code>
</Task>

该任务读取XML元素并从中创建项目。文本被转换为元数据。

然后,您可以编写如下的任务:

<Target Name="DeconstructPropertyXml">
  <TransformXmlToItem Xml="$(Person_2)">
    <Output TaskParameter="Elements" ItemName="Person_2I"/>
  </TransformXmlToItem>
  <Message Text="%(Person_2I.Identity) = %(Person_2I.text)" Importance="high"/>
</Target>

这应该只输出Name = Bob

您可以通过属性等方式添加其他元数据的方法是相同的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接