簡體   English   中英

C#LINQ和XML獲取子節點

[英]C# LINQ and XML Getting child nodes

遇到節點值時遇到問題。 不確定為什么以下代碼無法執行此操作。

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='STIG_unclass.xsl'?>
<Benchmark xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cpe="http://cpe.mitre.org/language/2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" id="Windows_7_STIG" xml:lang="en" xsi:schemaLocation="http://checklists.nist.gov/xccdf/1.1 http://nvd.nist.gov/schema/xccdf-1.1.4.xsd http://cpe.mitre.org/dictionary/2.0 http://cpe.mitre.org/files/cpe-dictionary_2.1.xsd" xmlns="http://checklists.nist.gov/xccdf/1.1">
    <status date="2015-06-16">accepted</status>
    <title>Windows 7 Security Technical Implementation Guide</title>
    <description>
        The Windows 7 Security Technical Implementation Guide (STIG) is published as a tool to improve the security of Department of Defense (DoD) information systems.  The requirements were developed from DoD consensus, as well as the Windows 7 Security Guide and security templates published by Microsoft Corporation.  Comments or proposed revisions to this document should be sent via e-mail to the following address:  disa.stig_spt@mail.mil.
    </description>
    <notice id="terms-of-use" xml:lang="en">Developed_by_DISA_for_the_DoD</notice>
    <reference href="http://iase.disa.mil">
        <dc:publisher>DISA, Field Security Operations</dc:publisher>
        <dc:source>STIG.DOD.MIL</dc:source>
    </reference>
    <plain-text id="release-info">Release: 20 Benchmark Date: 24 Jul 2015</plain-text>
</Benchmark>

示例XML文件。

以下是我的代碼。

String Title = LoadedXML.Element("Benchmark").Attribute("id").Value;
var XMLData = LoadedXML.Element("Benchmark").Elements("plain-text")
                 .Single(release => release.Attribute("id").Value == "release-info").Value;

有沒有辦法可以同時獲得多個Node值? 就像一次獲得標題和發布價值而不是每個單獨的一個?

Linq-to-xml通常用於查詢XML以過濾其節點,然后根據需要獲取所需的元素/值。 這更像是用SQL查詢表。

如果結果需要全部/大部分XML,那么更好的方法是將XMl解除分解為本機(此處為C#)對象並將其映射到所需的模型對象。 XML總是可以被認為是對象的序列化版本(盡管它也可以手動),並且可以反序列化回實際對象。

.Net對所有這些都有本機支持,有關詳細信息,請參閱用於XML序列化 序列化的 msdn鏈接。 您可以編寫一個小方法來反序列化您的對象。

using System.Xml.Linq;
using System.Xml.Serialization;

public class XMLHelper
{
    public T DeserializeData<T>(string data)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        StringReader reader = new StringReader(data);
        var deserializedObject = serializer.Deserialize(reader);
        return deserializedObject == null ? default(T) : (T)deserializedObject;
    }
}

要獲取字符串,您可以執行File.ReadAllText(xmlFilePath)或任何更容易的情況。

這將為您提供整個XML的deseialized對象。 如果您想要其他轉換對象,可以手動映射,也可以使用AutoMapper

您的代碼失敗,因為您的XML包含Namespace ,您無法直接訪問您的節點。 如果你想確認這只是查詢LoadedXML.Elements()並檢查調試器中的值,你可以清楚地看到那里的命名空間: -

在此輸入圖像描述

所以,你需要聲明命名空間並使用它: -

XNamespace ns = "http://checklists.nist.gov/xccdf/1.1";

如果你想同時獲取兩個vales,你可以將它投影到這樣的匿名類型: -

var result = LoadedXML.Root.Elements(ns + "plain-text")
                      .Where(x => (string)x.Attribute("id") == "release-info")
                      .Select(x => new
                             {
                                 Title = (string)x.Document.Root.Attribute("id"),
                                 XMLData = x.Value
                             }).FirstOrDefault();

這個查詢給我以下輸出: -

在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM