2012-11-13 38 views
0

我試圖解析vcxproj文件,使用 - 我可以在任何方法(我曾經嘗試XPathDocument中,的XElement,的XDocument ......實在不行)解析vcxproj用的XElement - 無法檢索內部導入

典型項目配置:

<?xml version="1.0" encoding="utf-8"?> 
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <ItemGroup Label="P"> ... </ItemGroup> 
    <ItemGroup> <C I="..." /> </ItemGroup> 
    <ItemGroup> <C I="..." /> </ItemGroup> 
    <ItemGroup> ... </ItemGroup>  
    <Import Project="aaaaa" /> 
    <PropertyGroup C="..." Label="..."> ... </PropertyGroup> 
    <Import Project="ooother" /> 
    <ImportGroup Label="E"> </ImportGroup> 
    <ImportGroup Label="I_NEED_THIS" C="..."> 
    <Import Project="other" Condition="x" Label="L" /> 
    <Import Project="I_NEED_THIS_VALUE" /> 
    </ImportGroup> 
    <Import Project="bbbbb" /> 
    <ImportGroup Label="Ex"> </ImportGroup> 
</Project> 

我試圖從與標籤I_NEED_THIS的ImportGroup內的項目(S),我想獲得所有這些,能夠檢查(如果有)的標籤,或條件...

我懷疑問題可能是有具有類似名稱的多個元素,所以我想只得到一個級別的時間,

XElement xmlTree = XElement.Load(projectPath); 
XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003"; 
List<XElement> projectElements = (
    from mainElement in xmlTree.Descendants(ns + "Project") 
    from subElement in mainElement.Elements() 
    select subElement 
).ToList(); 

if (projectElements.Count == 0) 
    MessageBox.Show("Nothing is working today"); 

以上,應遵循的幾個foreach循環...

foreach (XElement projectElement in projectElements) 
{ 
List<XElement> importElements = (
    from mainElement in projectElement.Descendants(ns + "ImportGroup") 
    from subElement in mainElement.Elements() 
    select subElement 
).ToList(); 
... 
} 

等等,但在測試甚至第一圈的時候,在projectElements的計數爲0 ...

我已經嘗試過了沒有命名空間,以及...

我缺少什麼? 謝謝你...

回答

1

你可以擺脫那些電話Descendants。直接調用Elements應該沒問題。這是如何實現這種使用簡單的循環:

// we can directly grab the namespace, it's better than hard-coding it 
XNamespace ns = xmlTree.Name.Namespace; 
// xmlTree itself is the Project element, just to make sure: 
Debug.Assert(xmlTree.Name.LocalName == "Project"); 

// the following is all elements named "ImportGroup" under "Project" 
var importGroups = xmlTree.Elements(ns + "ImportGroup"); 
foreach(XElement child in importGroups) 
{ 
    // the following are all "Import" elements under "ImportGroup" elements 
    var imports = child.Elements(ns + "Import"); 
    foreach (var importElem in imports) 
    { 
     Console.WriteLine(importElem.Attribute("Project").Value); 
    } 
} 

//This is the output: 
//other 
//I_NEED_THIS_VALUE 

或者,你可以使用下面的代碼,可直接前往包含屬性值"I_NEED_THIS_VALUE"第二個元素:

var elems = xmlTree.Elements(ns + "ImportGroup") 
    .Where(x => x.Attributes("Label").Any(xattr => xattr.Value == "I_NEED_THIS")) 
     .Elements(ns + "Import") 
     .Where(x => x.Attributes("Project").Any(xattr => xattr.Value == "I_NEED_THIS_VALUE")); 
+0

非常感謝你。 ..我將如何使用第二個版本,獲取屬性值,或查找它是否存在? – Thalia

+1

@Mihaela不客氣。假設你對'Import'元素下名爲'Project'的屬性感興趣,用第二個代碼的最後一行代替: 'Select(x => x.Attributes(「Project」))。 x.Value).ToArray();' 然後您將擁有一組屬性值。請注意,上面的代碼仍然假定'ImportGroup's有一個'Label',其值爲'I_NEED_THIS'。如果不是這種情況,您可能需要更改第二行。 –