最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Linq to XML : How to get element based on other elements in file - Stack Overflow

programmeradmin5浏览0评论

Consider the following xml file. I would like to get the ConnectionString Element if I already have the Environment/Name value and Application/Name selected from different ComboBoxes.

<?xml version="1.0" encoding="utf-8" ?>
<Environments>
    <Environment>
        <Name>DEV</Name>
        <Applications>
            <Application>
                <Name>App1</Name>
                <DBType>Oracle</DBType>
                <ConnectionString>CS1</ConnectionString>
                <Username>user_1</Username>
                <Password>pw_1</Password>               
            </Application>
            <Application>
                <Name>App2</Name>
                <DBType>Oracle</DBType>                     
                <ConnectionString>CS2</ConnectionString>
                <Username>user_2</Username>
                <Password>pw_2</Password>
            </Application>          
        </Applications>
    </Environment>
    <Environment>
        <Name>TEST 1</Name>
        <Applications>
            <Application>
                <Name>App1</Name>
                <DBType>Oracle</DBType> 
                <ConnectionString>CS3sername>
                <Password>pw_3</Password>               
            </Application>
            <Application>
                <Name>App2</Name>
                <DBType>Oracle</DBType>             
                <ConnectionString>CS4</ConnectionString>
                <Username>user_4</Username>
                <Password>pw_4</Password>
            </Application>  
        </Applications>
    </Environment>
</Environments>

This is what I have at the moment but it I don't get any results back.

XDocument xDocument = XDocument.Load("Environments.xml");
        IEnumerable<XElement> ConnectionString = xDocument
        .XPathSelectElements("/Environments/Environment/Applications/Application/ConnectionString")
        .Where(x => x.XPathSelectElements("/Environments/Environment/Name").All(x => x.Value.Equals(Environment1ComboBox.SelectedItem))
                && x.XPathSelectElements("/Environments/Environment/Applications/Application/Name").All(x => x.Value.Equals(Application1ComboBox.SelectedItem)))
        .ToList();

Consider the following xml file. I would like to get the ConnectionString Element if I already have the Environment/Name value and Application/Name selected from different ComboBoxes.

<?xml version="1.0" encoding="utf-8" ?>
<Environments>
    <Environment>
        <Name>DEV</Name>
        <Applications>
            <Application>
                <Name>App1</Name>
                <DBType>Oracle</DBType>
                <ConnectionString>CS1</ConnectionString>
                <Username>user_1</Username>
                <Password>pw_1</Password>               
            </Application>
            <Application>
                <Name>App2</Name>
                <DBType>Oracle</DBType>                     
                <ConnectionString>CS2</ConnectionString>
                <Username>user_2</Username>
                <Password>pw_2</Password>
            </Application>          
        </Applications>
    </Environment>
    <Environment>
        <Name>TEST 1</Name>
        <Applications>
            <Application>
                <Name>App1</Name>
                <DBType>Oracle</DBType> 
                <ConnectionString>CS3sername>
                <Password>pw_3</Password>               
            </Application>
            <Application>
                <Name>App2</Name>
                <DBType>Oracle</DBType>             
                <ConnectionString>CS4</ConnectionString>
                <Username>user_4</Username>
                <Password>pw_4</Password>
            </Application>  
        </Applications>
    </Environment>
</Environments>

This is what I have at the moment but it I don't get any results back.

XDocument xDocument = XDocument.Load("Environments.xml");
        IEnumerable<XElement> ConnectionString = xDocument
        .XPathSelectElements("/Environments/Environment/Applications/Application/ConnectionString")
        .Where(x => x.XPathSelectElements("/Environments/Environment/Name").All(x => x.Value.Equals(Environment1ComboBox.SelectedItem))
                && x.XPathSelectElements("/Environments/Environment/Applications/Application/Name").All(x => x.Value.Equals(Application1ComboBox.SelectedItem)))
        .ToList();
Share Improve this question edited yesterday Rico Strydom asked yesterday Rico StrydomRico Strydom 5711 gold badge8 silver badges28 bronze badges 0
Add a comment  | 

2 Answers 2

Reset to default 2

Here is another way via LINQ to XML by using Ancestors() method.

It allows to go directly to the ConnectionString element in one single statement while checking its ancestors values.

c#

void Main()
{
     const string FILENAME = @"e:\Temp\Environments.xml";

    string environmentName = "DEV"; //Environment1ComboBox.SelectedItem;
    string applicationName = "App2"; //Application1ComboBox.SelectedItem;
    
    XDocument xdoc = XDocument.Load(FILENAME);

    string connectionString = xdoc.Descendants("ConnectionString")?
        .Where(x => x.Ancestors("Environment").Elements("Name")
            .FirstOrDefault().Value == environmentName 
            &&
            x.Ancestors("Application").Elements("Name")
            .FirstOrDefault().Value == applicationName)
            .FirstOrDefault().Value;
    Console.WriteLine(connectionString);
}

Output

CS2

I wouldn't use XPath for this, to be honest. I'd do it in two steps for simplicity, one to get the environment, the other the application within it:

// Cast if you need to...
string environmentName = Environment1ComboBox.SelectedItem;
string applicationName = Application1ComboBox.SelectedItem;

// First get the matching environment.
var document = XDocument.Load("Environments.xml");
var environment = document.Root?
    .Elements("Environment")
    .FirstOrDefault(env => (string) env.Element("Name") == environmentName);
if (environment is null)
{
    // Report that the environment isn't found, and exit this code
}

// Now get the matching application within the environment.
var application = environment
    .Element("Applications")
    .Elements("Application")
    .FirstOrDefault(app => (string) app.Element("Name") == applicatoinName);
if (application is null)
{
    // Report that the application isn't found, and exit this code
}

// Now we can get the connection string.
string connectionString = (string) app.Element("ConnectionString");
发布评论

评论列表(0)

  1. 暂无评论