簡體   English   中英

使用LINQ to XML查詢元素時出錯

[英]Error on querying element using LINQ to XML

這是我擁有的XML文件的一小部分。(請參見下文)。

我可以讀取所需的內容,例如可以獲取類型消息等。但是在PreflightResultEntry部分中,有一組名為Var的元素,我需要“ <Var name="NumPages">8</Var>

 --     
 <PreflightResultEntry type="GeneralDocInfo">
    <PreflightResultEntryMessage xml:lang="en-US">
        <Message>457834a.pdf </Message>
        <StringContext>
            <BaseString>%FileInfo%</BaseString>
            <Const name="Category">GeneralDocInfo</Const>
            <Const name="ActionID">-1</Const>
            <Instance>
                <Var name="FileInfo">
                    <Var name="DIPath">/V/PitStop/Testing/Mike/Processed Docs on Success/457834a.pdf</Var>
                    <Var name="CreationDate">D:20120724153648-05'00'</Var>
                    <Var name="ModDate">D:20120725134534-04'00'</Var>
                    <Var name="Producer">Adobe PDF Library 10.0</Var>
                    <Var name="Creator">Acrobat PDFMaker 10.1 for Word</Var>
                    <Var name="Author">DOL Comments</Var>
                    <Var name="Title"/>
                    <Var name="Subject"/>
                    <Var name="Keywords"/>
                    <Var name="Trapped">1</Var>
                    <Var name="NumPages">8</Var>
                    <Var name="Major">1</Var>
                    <Var name="Minor">5</Var>
                    <Var name="WasRepairedOnOpen">0</Var>
                    <Var name="IsLinearized">0</Var>
                    <Var name="ContainsThumbnails">0</Var>
                    <Var name="LeftToRightReading">1</Var>
                    <Var name="ContainsJobTicket">0</Var>
                    <Var name="EncryptionType">1</Var>
                    <Var name="Permissions">-1</Var>
                    <Var name="PrinergyTraps">3</Var>
                </Var>
                <Location page="-1"/>
            </Instance>
        </StringContext>
    </PreflightResultEntryMessage>
</PreflightResultEntry>
      ---

在這里,我所得到的適用於消息和類型

  List<PitStopMessage> messages = XDocument.Load(file)
      .Descendants("PreflightResultEntryMessage")
      .Where(x => x.Parent != null )
      .Select(x => new PitStopMessage()
      {
          message = x.Element("Message").Value,
          type = x.Parent.Attribute("type").Value,
          xmllevel = x.Parent.Attribute("level") != null ? x.Parent.Attribute("level").Value : String.Empty,
          link = 0
      }).ToList();

只有在父元素PreflightResultEntry中退出時,才需要對元素var進行新查詢

這是我到目前為止所擁有的,但是給了我一個錯誤“對象引用未設置為對象的實例”。 這表明我在尋找什么(元素)不存在。

 List<PitStopPages> messages = XDocument.Load(file)
     .Descendants("PreflightResultEntryMessage")
     .Where(x => x.Parent != null && x.Parent.Attribute("type").Value == "GeneralDocInfo" && x.Parent.Element("Var").Value == "NumPages")
     .Select(x => new PitStopPages()
     {
         Pages = x.Parent.Attribute("name").Value
     }).ToList();

我建議使用XPath選擇所需的節點。 您可以使用XPathSelectElements方法並傳遞XPath 如果只需要選擇一個節點,則可以改用XPathSelectElement (不帶's')。

在您的情況下,我認為XPath應該是: /PreflightResultEntry//Var[@name='NumPages']

您可以在此處測試XPath

讓我進一步說明@AnhTriet的建議,

var xml = new XmlDocument();

xml.LoadXml(str);  // suppose that str string contains your xml

var xnList = xml.SelectNodes("/PreflightResultEntry//Var[@name='NumPages']");

foreach (XmlNode xn in xnList)
{
    Console.WriteLine(xn.InnerText); //this should print the 8
}

.NET小提琴

為了能夠使用XPathSelectElement方法,您需要首先使用XDocument類加載xml。

因此,將是這樣的:

var xml = XDocument.Load(file);

XmlNode node = xml.XPathSelectElement("/PreflightResultEntry//Var[@name='NumPages']");

Console.WriteLine(node.InnerText);

如果您在邏輯上通讀了您的查詢,則可能會發現錯誤。

您的查詢試圖找到:

  • 名為PreflightResultEntryMessage的元素
  • 如果其父項具有GeneralDocInfotype屬性
  • 其父元素的第一個子元素Var的值為NumPages
  • 獲取父元素的name屬性值

問題是最后兩個部分。 在所有情況下, Parent都是PreflightResultEntry元素。 PreflightResultEntry沒有任何子Var元素, Var元素沒有NumPages ,並且PreflightResultEntry沒有name屬性。 這些中的任何一個都會導致空引用異常(您正在看到的異常)。

最好是從上至下進行處理,而不是先查找一個元素然后再查找其父元素。 所以:

  • 查找稱為元素PreflightResultEntrytype的屬性GeneralDocInfo
  • 獲取后代Var元素的name屬性為NumPages

所以:

var numPages = (int)XDocument.Load(file)
        .Descendants("PreflightResultEntry")
        .Where(x => (string) x.Attribute("type") == "GeneralDocInfo")
        .Descendants("Var")
        .Single(x => (string) x.Attribute("name") == "NumPages");

請參閱此小提琴以獲得有效的演示。

暫無
暫無

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

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