我有什么
一个XML文档,其中节点名称具有严格的命名约定,其中每个节点的级别都反映在其名称中,如下所示:
<root>
<ABC>
<ABC_1/>
<ABC_2>
<ABC_2_1>
<ABC_2_1_1/>
</ABC_2_1>
<ABC_2_2/>
<ABC_2_5/>
<ABC_2_6/>
</ABC_2>
</ABC>
<DEF>
<DEF_1/>
<DEF_2/>
<DEF_59/>
</DEF>
...
</root>
兄弟姐妹的顺序始终保留(如图所示),但并不总是顺序的,即某些节点可能丢失(例如&#34; ABC_2_3&#34;以及&#34; ABC_2_4&#34;上面)。但是, do 存在的节点总是按升序插入。
我想做的事
我有一个简单的XPath用于其中一个缺失的节点,例如: &#34; // ABC_2_4&#34;,如果它不存在,我需要创建/插入具有该名称的新节点。我没有父节点或任何其他信息;我只有那个XPath字符串和XML文档/对象。
所以我所做的就是解析XPath来提取父节点名称(在这个例子中&#34; ABC_2&#34;),然后插入一个新的&#34; ABC_2_4&#34;节点进入该父节点。 (为简单起见,假设父节点将始终存在。)
问题
有没有&#34;技巧&#34;快速找到前一个兄弟,即以某种方式只用一两个查询,而不是从丢失的节点名称向后枚举,并尝试一次选择一个节点,直到找到现有的前一个兄弟?如果我需要插入&#34; DEF_58&#34;节点给出上面的示例XML(即&#34; DEF_2&#34;和#34; DEF_59&#34;),这将是一个非常长/慢的枚举,直到我找到现有的前兄弟(&#34; DEF_2& #34)...
一些笔记(如果可能有帮助):
谢谢!
答案 0 :(得分:1)
您可以使用substring-after
来获取名称中的最后一个数字,然后找到最后一个数字小于给定数字的节点。您需要使用substring-after
次,因为标记名称中有下划线。
//DEF/*[substring-after(name(), '_') < 58][last()]
//ABC_2/*[substring-after(substring-after(name(),'_'), '_') < 4][last()]
//ABC_2_1/*[substring-after(substring-after(substring-after(name(),'_'), '_'), '_') < 44][last()]
这些将分别为DEF_58
,ABC_2_4
和ABC_2_44
找到前面的兄弟姐妹。