我有以下名为Example.xml的XML文件。请注意根元素Message中的命名空间规范(xmlns),因为下面的问题与此有关。
OrderedDict([('Adityam', "('34', '2018-04-27 00:00:00'),No IMDB Info Available"),
('Baazaar', "('60', '2018-05-01 00:00:00'),N/A"),
('102 Not Out', "('75', '2018-05-04 00:00:00'),N/A"),
('3 Dev', "('0', '2018-05-11 00:00:00'),No IMDB Info Available"),
('Arjun Patiala', "('0', '2018-09-13 00:00:00'),No IMDB Info Available"),
('Ajay Devgn – Luv Ranjan’s Next', "('63', '2018-10-19 00:00:00'),No IMDB Info Available"),
('2.0', "('84', '2019-01-01 00:00:00'),8.5")])
我编写了以下函数来使用LINQ
返回一个字符串<?xml version="1.0" encoding="utf-8" ?>
<Message xmlns="http://www.myurl.com/Product" version="010" release="006">
<Header>
<To Qualifier="P" />
<From Qualifier="D" />
<MessageID>f244251a8c6c4070</MessageID>
<SentTime>2018-03-21T22:01:16.70Z</SentTime>
</Header>
<Body>
<Product>
<Description>
<Identification>
<ID1>1871598417</ID1>
<ID2>BE9432042-1234</ID2>
</Identification>
<Type>
<Name>Home Widget</Name>
<Category>Residential</Category>
</Type>
</Description>
</Product>
</Body>
</Message>
我遇到的问题是上述XML文件的返回值为空。
当我将根元素更改为仅如下所示:
Public Function GetProductDetail() As String
Dim xDoc As XDocument = Nothing
Dim returnValue As String = ""
Using xr As XmlReader = XmlReader.Create("C:\Automation\Example.xml")
xDoc = XDocument.Load(xr)
Dim query = From t In xDoc.Descendants("Body")
Select New With {Key _
.ID1 = t.Element("Product").Element("Description").Element("Identification").Element("ID1").Value,
.ID2 = t.Element("Product").Element("Description").Element("Identification").Element("ID2").Value,
.Name = t.Element("Product").Element("Description").Element("Type").Element("Name").Value}
For Each item In query
returnValue = $"ID1: {item.ID1} | ID2: {item.ID2} | Name: {item.Name}"
Next
End Using
Return returnValue
End Function
(即删除包括xmlns = ....在内的所有内容)我得到正确的返回值
returnValue = ID1:1871598417 | ID2:BE9432042-1234 |名称:家庭小工具
我有以下问题:
当xmlns是根元素的一部分时,我需要添加到我的代码或XPath Expression中。
有时XML文件可能不包含ID2元素。如何在LINQ查询中检查元素是否存在,或者甚至可以使用LINQ。
如果这与LINQ不合适,有人可以提供有关如何完成此操作的代码。
感谢每个人的投入,时间和帮助。
由于
Juzer
答案 0 :(得分:0)
问题是您没有为命名空间命名。
例如:
<Message xmlns:name="http://www.myurl.com/Product" version="010" release="006">
。
如果不为命名空间使用自定义名称,则必须使用整个命名空间作为标识符。
这是没有自定义名称的Body的名称
{{http://www.myurl.com/Product}Body}
这是自定义名称{Body}
(现在您将会问为什么元素正文的名称上没有前面的{name:Body}
,因为它没有任何命名影响)
您可以使用Null条件运算符
例如:t.Element("Product").Element("Description").Element("Identification").Element("ID1")?.Value
虽然这不是一个答案LINQ基本上是一种做复杂的foreach的方法。所以我唯一能做到的就是使用XPath而不是链接元素中的元素,其中任何一个元素都可能最终为空。
我希望我帮助过。如果出现任何问题,请随时提出,我会尝试解释。
谢谢,
修改强>
如果要使用命名空间查找xml节点,可以使用此类代码。 (如果我做错了,请饶恕我,我是C#Dev而不是Visual Basic)
Dim nameSpace As xDoc.Root.GetDefaultNamespace()?.NamespaceName
Dim body As xDoc.Descendants(XName.Get("Body", nameSpace))
Dim productXName As XName.Get("Product", nameSpace)
Dim descriptionXName As XName.Get("Description", nameSpace)
Dim identificationXName As XName.Get("Identification", nameSpace)
Dim id1XName As XName.Get("ID1", nameSpace)
Dim id2XName As XName.Get("ID2", nameSpace)
Dim typeXName As XName.Get("Type", nameSpace)
Dim nameXName As XName.Get("Name", nameSpace)
Dim query As From t In body
select New With {Key _
.ID1 = t.Element(productXName).Element(descriptionXName).Element(identificationXName).Element(id1XName)?.Value,
.ID2 = t.Element(productXName).Element(descriptionXName).Element(identificationXName).Element(id2XName)?.Value,
.Name = t.Element(productXName).Element(descriptionXName).Element(typeXName).Element(nameXName)?.Value}
'更新了工作VB.Net代码
Public Function GetProductDetail() As String
Dim xDoc As XDocument = Nothing
Dim returnValue As String = ""
Using xr As XmlReader = XmlReader.Create("C:\Automation\Example.xml")
xDoc = XDocument.Load(xr)
Dim xn = xDoc.Root.GetDefaultNamespace()?.NamespaceName
Dim body = xDoc.Descendants(XName.Get("Body", xn))
Dim productXName = XName.Get("Product", xn)
Dim descriptionXName = XName.Get("Description", xn)
Dim identificationXName = XName.Get("Identification", xn)
Dim id1XName = XName.Get("ID1", xn)
Dim id2XName = XName.Get("ID2", xn)
Dim typeXName = XName.Get("Type", xn)
Dim nameXName = XName.Get("Name", xn)
' Name1 May or Maynot exist in the XML file
Dim nameXName1 = XName.Get("Name1", xn)
' DT May or May not Exist in recived XML File
Dim query = From t In body
Select New With {Key _
.ID1 = t.Element(productXName).Element(descriptionXName).Element(identificationXName).Element(id1XName)?.Value,
.ID2 = t.Element(productXName).Element(descriptionXName).Element(identificationXName).Element(id2XName)?.Value,
.Name = t.Element(productXName).Element(descriptionXName).Element(typeXName).Element(nameXName)?.Value,
.DT = t.Element(productXName).Element(descriptionXName).Element(typeXName).Element(nameXName1)?.Value}
For Each item In query
returnValue = $"ID1: {item.ID1} | ID2: {item.ID2} | Name: {item.Name} | DT: {item.DT} "
Next
End Using
Return returnValue
End Function