代码之家  ›  专栏  ›  技术社区  ›  Rico Strydom

Linq to XML:如何基于文件中的其他元素获取元素

  •  0
  • Rico Strydom  · 技术社区  · 2 月前

    考虑以下xml文件。 我想得到 ConnectionString 如果我已经有了元素 Environment/Name 价值和 Application/Name 从不同的 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>
    

    这就是我现在所拥有的,但我没有得到任何结果。

    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();
    
    2 回复  |  直到 2 月前
        1
  •  1
  •   Yitzhak Khabinsky    2 月前

    这是通过LINQ to XML的另一种方法,使用 Ancestors() 方法。

    它允许直接进入 连接串 在检查其祖先值的同时,在一个语句中检查元素。

    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);
    }
    

    输出

    CS2
    
        2
  •  1
  •   Jon Skeet    2 月前

    说实话,我不会使用XPath来实现这一点。为了简单起见,我将分两步完成,一步是获取环境,另一步是其中的应用程序:

    // 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");