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

What is syntax of nested property of MSBuild?

我正在使用 MSBuild。

我正在通过 $(Person_1) 获取 Person_1 的值。如何获取 Person_2Name 子元素的值?我需要语法。

<PropertyGroup>
  <Person_1>Bob</Person_1>
  <Person_2>
    <Name>Bob</Name>
  </Person_2>
</PropertyGroup>

您正在混合属性和项目组。

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

属性定义为:

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

并使用 $(name) 语法访问。

项目组定义为:

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

并使用以下语法访问:%(Item.ItemProperty).

另见 this reference for the 'intuitive' syntax

回复:https://msdn.microsoft.com/en-us/library/ms171458.aspx 包含 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>

您需要一些高级的东西,例如内联任务:

<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.

与从属性等添加额外元数据的方式相同