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

Visual studio MSBuild的嵌套属性的语法是什么?,visual-studio,msbuild,Visual Studio,Msbuild,我正在使用MSBuild 我通过$(Person\u 1)获取Person\u 1的值。如何获取Person_2的Name子元素的值?我需要语法 <PropertyGroup> <Person_1>Bob</Person_1> <Person_2> <Name>Bob</Name> </Person_2> </PropertyGroup> 上下快速移动 上下快速移动 您正在混合

我正在使用MSBuild

我通过
$(Person\u 1)
获取
Person\u 1
的值。如何获取
Person_2
Name
子元素的值?我需要语法

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

上下快速移动
上下快速移动

您正在混合属性和项目组

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

属性定义为:

<PropertyGroup>
    <name>value</name>
</Propertygroup>
使用以下语法访问和:
%(Item.ItemProperty)

另请参见: 包含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>


();
而(!xr.EOF){
if(xr.NodeType==XmlNodeType.Element){
变量项=新任务项(xr.Name);
var text=xr.ReadElementContentAsString();
如果(!string.IsNullOrWhiteSpace(text)){
项目.SetMetadata(“文本”,文本);
}
}
xr.Read();
}
元素=items.ToArray();
}
]]>

该任务读取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


同样,您可以从属性等中添加额外的元数据。

不,我认为您是不对的。看这里的“将XML存储在属性中”一章:嗯,那还是同样的问题,不是吗?现在,您将在(平面)属性中存储xml值,而不是文字文本值。语法有误导性,但对于msbuild来说,这仍然是一个具有单个(在本例中为xml)值的简单属性。请注意,该示例具体限制了构造的xml值的使用:
属性可以包含任意xml,这有助于将值传递给任务或显示日志信息。
。它并没有说您可以使用msbuild语法读取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>