我正在尝试检查xml文件中是否存在属性为“ id ”的节点disp-formula
,该属性包含的值为deqnX-Y
,其中X
}和Y
是整数,如果匹配,则在字典中以下面的方式添加它们
Key Value
"rid="deqnX"" "rid="deqnX-Y""
"rid="deqnX+1"" "rid="deqnX-Y""
... ...
"rid="deqnY"" "rid="deqnX-Y""
incrementing value of X by 1 till it reaches Y
我已经尝试了下面的代码,但是卡在中途,我无法弄清楚要做什么。
Dictionary<string, string> dict = new Dictionary<string, string>();
XDocument doc = XDocument.Load(@"D:\Practice\test.xml",LoadOptions.PreserveWhitespace);
var x =from y in doc.Descendants("disp-formula")
where y.Attribute("id").Value.Contains(@"deqn(\d+)-(\d+)")
select y.Attribute("id");
foreach (var item in x)
{
dict.Add(item);
}
以下是一个示例xml文件
<?xml version="1.0" encoding="UTF-8"?>
<article article-type="research">
<front>
<journal-meta>
<issn pub-type="paper">0327-286X</issn>
<publisher>
<publisher-name>IEEE</publisher-name>
</publisher>
</journal-meta>
<article-meta>
<article-id pub-id-type="doi">10.1245/11.202136</article-id>
<title-group>
<article-title>Dragon Ball Super popularity in USA</article-title>
</title-group>
</article-meta>
</front>
<body>
<sec id="S1">
<label>1.</label>
<p>....
<disp-formula id="deqn1">
...
</disp-formula>
</p>
</sec>
<sec id="S2">
<label>2.</label>
<p>...
<disp-formula id="deqn2-6">
...
</disp-formula></p>
<p>...
<disp-formula id="deqn7">
...
</disp-formula>
</p>
<p><disp-formula id="deqn8-10">
...
</disp-formula></p>
</sec>
</body>
</article>
这应该是运行程序后的字典项
Key Value
"rid="deqn2"" "rid=""deqn2-6""
"rid="deqn3"" "rid=""deqn2-6""
"rid="deqn4"" "rid=""deqn2-6""
"rid="deqn5"" "rid=""deqn2-6""
"rid="deqn6"" "rid=""deqn2-6""
"rid="deqn8"" "rid=""deqn8-10""
"rid="deqn9"" "rid=""deqn8-10""
"rid="deqn10"" "rid=""deqn8-10""
答案 0 :(得分:5)
此问题包括:
var dict = new Dictionary<string, string>();
var xdoc = XDocument.Load(@"D:\Practice\test.xml", LoadOptions.PreserveWhitespace);
var regex = new Regex(@"deqn(\d+)-(\d+)");
// Get matches by the regex
var matches = from dispFormula in xdoc.Descendants("disp-formula")
select regex.Match(dispFormula.Attribute("id").Value);
// We want only successes
matches = matches.Where(match => match.Success);
foreach (var match in matches)
{
// If input string is "deqn2-6",
// match.Groups[0].Value = "deqn2-6",
// match.Groups[1].Value = "2",
// match.Groups[2].Value = "6", so
int x = int.Parse(match.Groups[1].Value);
int y = int.Parse(match.Groups[2].Value);
// Now we have to increment x until y
for (int i = 0; x + i <= y; i++)
{
dict.Add($"deqn{x + i}", $"deqn{x}-{y}");
}
}
foreach (var entry in dict)
{
Console.WriteLine($"Key={entry.Key}, Value={entry.Value}");
}
此输出
Key=deqn2, Value=deqn2-6
Key=deqn3, Value=deqn2-6
Key=deqn4, Value=deqn2-6
Key=deqn5, Value=deqn2-6
Key=deqn6, Value=deqn2-6
Key=deqn8, Value=deqn8-10
Key=deqn9, Value=deqn8-10
Key=deqn10, Value=deqn8-10
答案 1 :(得分:2)
Dictionary<string, string> dict = new Dictionary<string, string>();
var regex = new Regex(@"deqn(\d+)-(\d+)");
XDocument doc = XDocument.Load(@"D:\Practice\test.xml", LoadOptions.PreserveWhitespace);
var x = from y in doc.Descendants("disp-formula")
let m = regex.Match(y.Attribute("id").Value)
where m.Success
select m;
foreach (var item in x)
{
var from = int.Parse(item.Groups[1].Value);
var to = int.Parse(item.Groups[2].Value);
for (int i = from; i <= to; i++)\\< should be <=
dict.Add("deqn" + i, item.Value);
}
答案 2 :(得分:1)
我已经测试了您的代码,但它不适用于您提供的Xml
所以最好使用Regex
来查找序列,如下面的代码所示:
Dictionary<string, string> dict = new Dictionary<string, string>();
XDocument doc = XDocument.Load(@"C:\Practice\test.xml", LoadOptions.PreserveWhitespace);
Regex reg = new Regex(@"deqn(\d+)-(\d+)");
var x = from y in doc.Descendants("disp-formula").ToList()
where reg.IsMatch(y.Attribute("id").Value)
select y.Attribute("id");
正如我在评论中告诉您的那样,您无法将item
添加到dic
,对于计数器,您还可以使用Regex
获取第一个数字,然后将其增加为:
int counter = 0;
foreach (var item in x)
{
var str = item.Value.Split('-')[0];
if (counter == 0)
counter = Convert.ToInt16(new Regex(@"\d+$").Match(str).Value) - 1;
dict.Add("deqn" + (counter++).ToString(), item.Value);
}
真正的工作代码是:
int counter = 0;
Dictionary<string, string> dict = new Dictionary<string, string>();
XDocument doc = XDocument.Load(@"C:\Practice\test.xml", LoadOptions.PreserveWhitespace);
Regex reg = new Regex(@"deqn(\d+)-(\d+)");
(from y in doc.Descendants("disp-formula").ToList()
where reg.IsMatch(y.Attribute("id").Value)
select y.Attribute("id")).ToList().ForEach(item=>
{
if (counter == 0)
counter = Convert.ToInt16(new Regex(@"\d+$").Match(item.Value.Split('-')[0]).Value) - 1;
dict.Add("deqn" + (++counter).ToString(), item.Value);
});
答案 3 :(得分:1)
这是我想要构建的最终程序
string[] path=Directory.GetDirectories(textBox1.Text,"xml",SearchOption.AllDirectories)
.SelectMany(x=>Directory.GetFiles(x,"*.xml",SearchOption.AllDirectories)).ToArray();
Dictionary<string, string> dict = new Dictionary<string, string>();
var regex = new Regex(@"deqn(\d+)-(\d+)");
foreach (var file in path) {
dict.Clear();
XDocument doc = XDocument.Load(file, LoadOptions.PreserveWhitespace);
var x = from y in doc.Descendants("disp-formula")
let m = regex.Match(y.Attribute("id").Value)
where m.Success
select m;
foreach (var item in x)
{
var from = int.Parse(item.Groups[1].Value);
var to = int.Parse(item.Groups[2].Value);
for (int i = from; i <= to; i++)
dict.Add("rid=\"deqn" + i+"\"", "rid=\""+item.Value+"\"");
foreach (KeyValuePair<string,string> element in dict) {
string text=File.ReadAllText(file);
text=text.Replace(element.Key,element.Value);
File.WriteAllText(file, text);
}
}
}
MessageBox.Show("Done");
感谢@lomed和@Mike Mat帮我解决这个问题......:)