仅当子元素具有特定数量的元素时,才选择父元素
本文关键字:元素 选择 | 更新日期: 2023-09-27 17:55:14
我正在尝试获取<PlanarGeometry>
<Polyloop>
编号为 CartesianPoint
> 4 的所有<Opening>
标签。
XML 标记图面是另一个标记图面的子图面。
<Surface id="su-137" surfaceType="InteriorWall" constructionIdRef="ASHIW23" xmlns="http://www.gbxml.org/schema">
<Name>W-106-114-I-W-137</Name>
<Opening id="su-137-op-1" openingType="NonSlidingDoor" constructionIdRef="MDOOR">
<Name>W-106-114-I-W-137-D-1</Name>
<PlanarGeometry>
<PolyLoop>
<CartesianPoint><Coordinate>55.570238</Coordinate><Coordinate>92.571596</Coordinate>
<Coordinate>0.000000</Coordinate></CartesianPoint><CartesianPoint> <Coordinate>55.570238</Coordinate><Coordinate>92.571596</Coordinate><Coordinate>6.666667</Coordinate>
</CartesianPoint>
<CartesianPoint>
<Coordinate>55.570238</Coordinate><Coordinate>95.571596</Coordinate><Coordinate>6.666667</Coordinate></CartesianPoint>
<CartesianPoint>
<Coordinate>55.570238</Coordinate><Coordinate>95.571596</Coordinate><Coordinate>0.000000</Coordinate>
</CartesianPoint>
</PolyLoop>
</PlanarGeometry>
</Opening>
</Surface>
我从中得到的参考很少 - Xpath 仅选择存在子元素的节点?SO线程,从下面的示例中得到了很少的帮助。
book[author/degree]
All <book> elements that contain <author> children that in turn contain at least one <degree> child.
如何使用 xPath 或其他方式实现此目的???
我正在尝试获取所有
<Opening>
标签,其<PlanarGeometry>
的<Polyloop>
具有笛卡尔点> 4 的编号。
假设 Surface
元素是您当前的上下文节点,则:
gb:Opening[gb:PlanarGeometry/gb:Polyloop[count(gb:CartesianPoint) > 4]]
gb
前缀需要映射到http://www.gbxml.org/schema
命名空间 URI。 这将选择包含至少一个Polyloop
且子元素超过 4 个CartesianPoint
的所有Opening
元素。
以下 XPath 应该可以工作:
//g:Opening[4<count(./g:PlanarGeometry/g:PolyLoop/g:CartesianPoint)]
请注意,它使用命名空间前缀,因为 Surface
标记具有命名空间。我不太了解 C#,但您可能必须先注册前缀才能使用它。
请尝试一下:
/gb:Surface/gb:Opening[count(gb:PlanarGeometry/gb:PolyLoop/gb:CartesianPoint) > 4]
如此处所示,由于 XML 使用命名空间,因此需要向 XPath 引擎声明该命名空间,然后通过前缀引用它。 它不一定是gb
,但它必须是某种东西。
如果你喜欢使用 LINQ to XML,这里是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
public class Program
{
public static void Main()
{
XElement sample = XElement.Load("c:''sample.xml");
IEnumerable<XElement> open_elements = sample.Descendants().Where(c => c.Name.LocalName == "Opening").Where(c => c.Descendants().Where(d => d.Name.LocalName == "CartesianPoint").Count() > 4);
foreach (XElement ele in open_elements){
Console.Write(ele.Attribute("id"));
}
Console.ReadKey();
}
}
}
希望这有帮助。