提问人:Helen Araya 提问时间:6/29/2023 最后编辑:Helen Araya 更新时间:6/29/2023 访问量:72
XmlDocument 将 xpath 属性值中的科学记数法解析为数字
XmlDocument Parse scientific notation in xpath attribute value to a number
问:
我有XML,其中的值以科学记数法保存,我需要对该值进行一些比较。但是科学记数法没有按预期工作。
以下是我的代码:
XmlDocument doc = new XmlDocument();
doc.LoadXml("<MainLevel><SubLevel Name=\"test\" Amount=\"0.0E0\"></SubLevel></MainLevel>");
XmlNodeList? xmlLevelsList1 = doc.SelectNodes("MainLevel/SubLevel[@Amount<=275.00]");// this does not return anything because 0.0E0 is in scientific notation
doc.LoadXml("<MainLevel><SubLevel Name=\"test\" Amount=\"0.00\"></SubLevel></MainLevel>");
XmlNodeList? xmlLevelsList2 = doc.SelectNodes("MainLevel/SubLevel[@Amount<=275.00]"); this does not return anything because 0.00 is a good format
我想返回 1 个节点而不是 0 个节点。它返回 0,因为xmlLevelsList1
“0.0E0”不是有效数字。
答:
0赞
LMC
6/29/2023
#1
number()
函数可以在 XPath 1.0 中使用
/MainLevel/SubLevel[number(@Amount) <= 275.00]
鉴于
<?xml version="1.0" encoding="utf-8" ?>
<MainLevel>
<SubLevel Name="test" Amount="0.0E0"></SubLevel>
<SubLevel Name="test1" Amount="10.0E1"></SubLevel>
<SubLevel Name="test1" Amount="4.0E5"></SubLevel>
<SubLevel Name="test1" Amount="2.75E2"></SubLevel>
<SubLevel Name="test1" Amount="2.76E2"></SubLevel>
</MainLevel>
会回来
<SubLevel Name="test" Amount="0.0E0"/>
<SubLevel Name="test1" Amount="10.0E1"/>
<SubLevel Name="test1" Amount="2.75E2"/>
经测试,用途广泛xmllint
libxml2
xmllint --xpath '/MainLevel/SubLevel[number(@Amount) <= 275.00]' tmp.xml
<SubLevel Name="test" Amount="0.0E0"/>
<SubLevel Name="test1" Amount="10.0E1"/>
<SubLevel Name="test1" Amount="2.75E2"/>
使用 python 进行测试lxml
from lxml import etree
tree = etree.parse("tmp.xml")
[e.get('Amount') for e in tree.xpath('/MainLevel/SubLevel[number(@Amount) <= 275.00]')]
['0.0E0', '10.0E1', '2.75E2']
评论
0赞
Helen Araya
6/29/2023
由于某种原因,这对我不起作用?我正在使用一个简单的控制台 C# 应用程序。
0赞
Yitzhak Khabinsky
6/29/2023
我在 c# 中尝试了这种方法。它不起作用。😒
0赞
LMC
6/29/2023
我相信这取决于 XPath 的实现。我用那个实现测试了它。xmllint
libxml2
0赞
Yitzhak Khabinsky
6/29/2023
.Net Framework 位于 XML 技术栈 v.1.0(大约 1999-2001 年)上,包括:XPath、XSLT 和 XSD。不支持 XQuery,仅在 MS SQL Server 中。
0赞
LMC
6/29/2023
找不到任何可用功能和 .NET 内容的文档。您可以尝试这个简单的XPath,看看它是如何工作的。它应该返回number("10.0E2")
1000
1赞
Yitzhak Khabinsky
6/29/2023
#2
最好使用 LINQ to XML API。自 2007 年以来,它在 .Net Framework 中可用。
正如@zx485已经指出的那样:“XSLT 1.0 不支持科学记数法。
因此,我们不能使用 XPath 表达式。
在 .Net 端转换为双精度数据类型即可完成这项工作。
c#
void Main()
{
XDocument doc = XDocument.Parse(@"<MainLevel>
<SubLevel Name='test' Amount='0.0E0'></SubLevel>
<SubLevel Name='test1' Amount='10.0E1'></SubLevel>
<SubLevel Name='test1' Amount='4.0E5'></SubLevel>
<SubLevel Name='test1' Amount='2.75E2'></SubLevel>
<SubLevel Name='test1' Amount='2.76E2'></SubLevel>
</MainLevel>");
var xmlLevelsList1 = doc.Descendants("SubLevel")
.Where(d => double.Parse(d.Attribute("Amount").Value) <= 275.00);
Console.WriteLine(xmlLevelsList1);
}
输出
<SubLevel Name="test" Amount="0.0E0"></SubLevel>
<SubLevel Name="test1" Amount="10.0E1"></SubLevel>
<SubLevel Name="test1" Amount="2.75E2"></SubLevel>
评论
0赞
Helen Araya
6/29/2023
我的是 XMLDocument,我没有使用 Linq。有XmlDocument的解决方案吗?
0赞
Michael Kay
6/29/2023
很简单,只需使用 XPath 2.0+ 处理器,例如 Saxon。
1赞
Yitzhak Khabinsky
6/29/2023
@HelenAraya,XMLDocument 它是一种古老的数据类型,大约在 2002 - 2006 年。从 2007 年开始,LINQ to XML 在 .Net Framework 中“取代”了它。
0赞
Martin Honnen
6/29/2023
#3
使用 Saxon.NET:
using System.Xml;
using Saxon.Api;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<MainLevel><SubLevel Name=\"test\" Amount=\"0.0E0\"></SubLevel></MainLevel>");
XmlNodeList? xmlLevelsList1 = doc.SelectNodes("MainLevel/SubLevel[@Amount<=275.00]");// this does not return anything because 0.0E0 is in scientific notation
Console.WriteLine(xmlLevelsList1.Count);
Processor processor = new Processor();
var docBuilder = processor.NewDocumentBuilder();
var xdmDoc = docBuilder.Wrap(doc);
var xpathCompiler = processor.NewXPathCompiler();
var xdmResult = xpathCompiler.Evaluate("MainLevel/SubLevel[@Amount<=275.00]", xdmDoc);
Console.WriteLine(xdmResult.Count);
输出:
0
1
请注意,虽然您可以针对 Microsoft DOM(即 XmlDocument/XmlNode)运行 XPath 3.1,但 Saxon 有自己的树模型,建议仅在您有无法切换到 Saxon 的本机树模型的旧代码时才使用 Microsoft DOM。
上一个:xpath:所有节点都有例外?
评论
fn:number(...)