这是我所拥有的XML文件的一小部分。(见下文)。
我能够阅读我需要的内容,例如我可以获得类型和消息等,但是在其中一个 PreflightResultEntry section有一组名为Var的元素我需要&#34; <Var name="NumPages">8</Var>
&#34;
--
<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进行新查询这里我到目前为止,但它给了我一个错误&#34;对象引用未设置为对象的实例。&#34;这说明了我所寻找的(元素)不存在。
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();
答案 0 :(得分:0)
我建议使用XPath来选择所需的节点。您可以使用方法XPathSelectElements并传入XPath
。如果您只需要选择一个节点,则可以使用XPathSelectElement(不用&#39; s&#39;)代替。
在您的情况下,我认为XPath
应该是:/PreflightResultEntry//Var[@name='NumPages']
您可以测试XPath
here。
答案 1 :(得分:0)
让我扩展一下@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
}
为了能够使用XPathSelectElement
方法,您需要先使用XDocument
类加载xml
所以,它会是这样的:
var xml = XDocument.Load(file);
XmlNode node = xml.XPathSelectElement("/PreflightResultEntry//Var[@name='NumPages']");
Console.WriteLine(node.InnerText);
答案 2 :(得分:0)
如果您在逻辑上阅读了查询,则可能会发现错误。
您的查询正在尝试查找:
PreflightResultEntryMessage
type
属性为GeneralDocInfo
Var
的子元素的值为NumPages
name
属性值问题是最后两部分。在所有情况下Parent
都是PreflightResultEntry
元素。 PreflightResultEntry
没有任何子Var
元素,没有Var
元素具有值 NumPages
,PreflightResultEntry
没有name
1}}属性。其中任何一个都会导致空引用异常(您看到的异常)。
最好从上到下处理这个问题,而不是找到一个元素,然后回头查看它的父元素。所以:
PreflightResultEntry
且type
属性为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");
有关正常工作的演示,请参阅this fiddle。