查找并编号连续 XML 个元素
Find and number consecutive XML elements
我有一份 XML 文档,看起来有点像这样:
<root>
Maybe some text
<thing>thing can have text</thing>
<thing>it can even be on multiple
lines
</thing>
<thing>a third thing</thing>
This text resets the numbering
<thing>this thing is not part of the above list and should have number 1</thing>
<some-element-not-thing>Also resets numbering</some-element-not-thing>
<thing>this thing should also have number 1<thing/>
</root>
我需要在 <thing>
连续出现时给它们编号,方法是给每个属性一个名为 "number" 的属性。也就是说,我想要的结果是:
<root>
Maybe some text
<thing number="1">thing can have text</thing>
<thing number="2">it can even be on multiple
lines
</thing>
<thing number="3">a third thing</thing>
This text resets the numbering
<thing number="1">this thing is not part of the above list and should have number 1</thing>
<some-element-not-thing>Also resets numbering</some-element-not-thing>
<thing number="1">this thing should also have number 1<thing/>
</root>
我将如何处理这样的事情?我看不到在 XmlDocument 中的元素之间查找文本的方法(但它确实允许我按顺序枚举元素,因此当我遇到不是 <thing>
的内容时我可以重置编号),而且我不确定 LINQ to XML 允许我在元素之间获取文本,因为它只会产生元素或后代,它们都不代表 "loose text"。
也许这个 "loose text" 不好(但显然可以解析)XML?
编辑:我完全误解了自己的问题。显然元素之间没有文本,这是我后来修复的错误的结果。我最终使用的解决方案只是枚举节点并以这种方式更改它们的属性(使用 XML Document 并忽略空格),类似于下面的建议。我很抱歉没有在我的脑海中更多地思考这个问题 and/or 花更多的时间进行研究。如果人们认为这个问题对 SO 没有足够的贡献,我不介意删除它。
一如既往,如果您在提问之前提供您已经尝试过的内容,将会很有帮助。有很多关于解析和操作的博文和问题 XML。
作为开始,我会使用 LINQ 来解析 XML。然后您所要做的就是遍历根元素下的节点,为每个 thing
元素分配一个递增的数字。当下一个元素不是 thing
且不是空白时,此计数器会重置:
var doc = XDocument.Parse(xml, LoadOptions.PreserveWhitespace);
var i = 0;
foreach (var node in doc.Root.Nodes())
{
var element = node as XElement;
var text = node as XText;
var isThing = element != null && element.Name == "thing";
var isWhitespace = text != null && string.IsNullOrWhiteSpace(text.Value);
if (isThing)
{
element.Add(new XAttribute("number", ++i));
}
else if (!isWhitespace)
{
i = 0;
}
}
var result = doc.ToString();
我有一份 XML 文档,看起来有点像这样:
<root>
Maybe some text
<thing>thing can have text</thing>
<thing>it can even be on multiple
lines
</thing>
<thing>a third thing</thing>
This text resets the numbering
<thing>this thing is not part of the above list and should have number 1</thing>
<some-element-not-thing>Also resets numbering</some-element-not-thing>
<thing>this thing should also have number 1<thing/>
</root>
我需要在 <thing>
连续出现时给它们编号,方法是给每个属性一个名为 "number" 的属性。也就是说,我想要的结果是:
<root>
Maybe some text
<thing number="1">thing can have text</thing>
<thing number="2">it can even be on multiple
lines
</thing>
<thing number="3">a third thing</thing>
This text resets the numbering
<thing number="1">this thing is not part of the above list and should have number 1</thing>
<some-element-not-thing>Also resets numbering</some-element-not-thing>
<thing number="1">this thing should also have number 1<thing/>
</root>
我将如何处理这样的事情?我看不到在 XmlDocument 中的元素之间查找文本的方法(但它确实允许我按顺序枚举元素,因此当我遇到不是 <thing>
的内容时我可以重置编号),而且我不确定 LINQ to XML 允许我在元素之间获取文本,因为它只会产生元素或后代,它们都不代表 "loose text"。
也许这个 "loose text" 不好(但显然可以解析)XML?
编辑:我完全误解了自己的问题。显然元素之间没有文本,这是我后来修复的错误的结果。我最终使用的解决方案只是枚举节点并以这种方式更改它们的属性(使用 XML Document 并忽略空格),类似于下面的建议。我很抱歉没有在我的脑海中更多地思考这个问题 and/or 花更多的时间进行研究。如果人们认为这个问题对 SO 没有足够的贡献,我不介意删除它。
一如既往,如果您在提问之前提供您已经尝试过的内容,将会很有帮助。有很多关于解析和操作的博文和问题 XML。
作为开始,我会使用 LINQ 来解析 XML。然后您所要做的就是遍历根元素下的节点,为每个 thing
元素分配一个递增的数字。当下一个元素不是 thing
且不是空白时,此计数器会重置:
var doc = XDocument.Parse(xml, LoadOptions.PreserveWhitespace);
var i = 0;
foreach (var node in doc.Root.Nodes())
{
var element = node as XElement;
var text = node as XText;
var isThing = element != null && element.Name == "thing";
var isWhitespace = text != null && string.IsNullOrWhiteSpace(text.Value);
if (isThing)
{
element.Add(new XAttribute("number", ++i));
}
else if (!isWhitespace)
{
i = 0;
}
}
var result = doc.ToString();