This query isn't working as I'm expecting it to. Anyone see the problem?
这个查询不像我预期的那样有效。有人看到这个问题吗?
I'm trying to get an element by it's name, but it's not returning anything. Here is the specific part of the function I need some help with:
我试图通过它的名字获取一个元素,但是它没有返回任何东西。这里是我需要一些帮助的具体部分:
Update
更新
The solution was to use an XName instead of a string. Like so:
解决方案是使用XName而不是字符串。像这样:
var matchingElements = elements.Where(e => e.Name.Equals(XName.Get(name)));
3 个解决方案
#1
3
Try changing your line to:
试着改变你的路线:
elements.Where(e => e.Name.LocalName == name)
The LocalName
part is the important part, as otherwise you are comparing equality of an XName
with a string
. Remember, XML supports names of the style "prefix:element-name". In that example, "prefix" is the identifier associated with the namespace returned by e.Name.Namespace
and "element-name" is the identifier returned by e.Name.LocalName
.
LocalName部分是重要的部分,否则您将比较XName与字符串的相等性。记住,XML支持样式“前缀:元素名称”的名称。在该示例中,“前缀”是与e.namename返回的名称空间相关联的标识符。命名空间和“元素名称”是e.Name.LocalName返回的标识符。
#2
2
Kirk's answer is right on the money. I wanted to point out a few issues with your code.
柯克的答案在金钱上是正确的。我想指出您的代码中的一些问题。
This line unnecessarily counts all the elements:
这一行不必要地计算了所有要素:
var hasMatch = matchingElements.Count() > 0;
You can replace it with Any()
which will terminate early once an element is found:
您可以用任何()替换它,一旦找到一个元素,这些()将尽早终止:
var hasMatch = matchingElements.Any();
Next, having verified that hasMatch
is true
you should call First()
instead of FirstOrDefault()
since you know it has to have a value at that point.
接下来,验证了hasMatch是正确的,您应该调用First()而不是FirstOrDefault(),因为您知道它在这一点上必须有一个值。
Having said that, you could actually rewrite your code as follows:
话虽如此,实际上您可以重写代码如下:
var matchingElement = elements.FirstOrDefault(e => e.Name.LocalName == name);
return (string)matchingElement;
Here casting to a string
will return the value of the element if it was found, otherwise it would return null
. The cast is used just in case it was null
since you wouldn't be able to use matchingElement.Value
which would throw a NullReferenceException
if no element was found. You should also consider using SingleOrDefault
if you expect only one element to exist.
在这里,如果找到一个字符串,那么将返回元素的值,否则将返回null。cast只是在它为null时使用,因为您无法使用matchingElement。值,如果没有找到元素,将抛出NullReferenceException。如果您希望只有一个元素存在,还应该考虑使用SingleOrDefault。
#3
1
I think you need to add the root namespace to the name of the element. You can also try using the XContainer.Descendants(XName)
method instead.
我认为您需要将根名称空间添加到元素的名称中。您还可以尝试使用XContainer.Descendants(XName)方法。
#1
3
Try changing your line to:
试着改变你的路线:
elements.Where(e => e.Name.LocalName == name)
The LocalName
part is the important part, as otherwise you are comparing equality of an XName
with a string
. Remember, XML supports names of the style "prefix:element-name". In that example, "prefix" is the identifier associated with the namespace returned by e.Name.Namespace
and "element-name" is the identifier returned by e.Name.LocalName
.
LocalName部分是重要的部分,否则您将比较XName与字符串的相等性。记住,XML支持样式“前缀:元素名称”的名称。在该示例中,“前缀”是与e.namename返回的名称空间相关联的标识符。命名空间和“元素名称”是e.Name.LocalName返回的标识符。
#2
2
Kirk's answer is right on the money. I wanted to point out a few issues with your code.
柯克的答案在金钱上是正确的。我想指出您的代码中的一些问题。
This line unnecessarily counts all the elements:
这一行不必要地计算了所有要素:
var hasMatch = matchingElements.Count() > 0;
You can replace it with Any()
which will terminate early once an element is found:
您可以用任何()替换它,一旦找到一个元素,这些()将尽早终止:
var hasMatch = matchingElements.Any();
Next, having verified that hasMatch
is true
you should call First()
instead of FirstOrDefault()
since you know it has to have a value at that point.
接下来,验证了hasMatch是正确的,您应该调用First()而不是FirstOrDefault(),因为您知道它在这一点上必须有一个值。
Having said that, you could actually rewrite your code as follows:
话虽如此,实际上您可以重写代码如下:
var matchingElement = elements.FirstOrDefault(e => e.Name.LocalName == name);
return (string)matchingElement;
Here casting to a string
will return the value of the element if it was found, otherwise it would return null
. The cast is used just in case it was null
since you wouldn't be able to use matchingElement.Value
which would throw a NullReferenceException
if no element was found. You should also consider using SingleOrDefault
if you expect only one element to exist.
在这里,如果找到一个字符串,那么将返回元素的值,否则将返回null。cast只是在它为null时使用,因为您无法使用matchingElement。值,如果没有找到元素,将抛出NullReferenceException。如果您希望只有一个元素存在,还应该考虑使用SingleOrDefault。
#3
1
I think you need to add the root namespace to the name of the element. You can also try using the XContainer.Descendants(XName)
method instead.
我认为您需要将根名称空间添加到元素的名称中。您还可以尝试使用XContainer.Descendants(XName)方法。