XPath和棘手的嵌套节点

时间:2012-12-06 21:29:58

标签: xml xpath

鉴于以下棘手的XML:

<Type>
    <ID></ID>
    <Name></Name>
    <Child>
        <Type>
            <ID></ID>
            <Name></Name>
            <Child>
                <Type>
                    <ID></ID>
                    <Name></Name>
                    <Child>
                        <Type>
                            <ID></ID>
                            <Name></Name>
                            <Child>
                                <Type>
                                    <ID></ID>
                                    <Name>FIND ME</Name>
                                </Type>
                            </Child>
                        </Type>
                    </Child>
                </Type>
            </Child>
        </Type>
    </Child>
</Type>

是否可以获得最深的类型名称字段?我尝试过这样的结构:

//*not(*)

但没有结果..

2 个答案:

答案 0 :(得分:4)

<强>予。这个简短而简单的XPath 1.0表达式:

//*[not(../*/*)]

根据提供的XML文档进行评估

<Type>
    <ID></ID>
    <Name></Name>
    <Child>
        <Type>
            <ID></ID>
            <Name></Name>
            <Child>
                <Type>
                    <ID></ID>
                    <Name></Name>
                    <Child>
                        <Type>
                            <ID></ID>
                            <Name></Name>
                            <Child>
                                <Type>
                                    <ID></ID>
                                    <Name>FIND ME</Name>
                                </Type>
                            </Child>
                        </Type>
                    </Child>
                </Type>
            </Child>
        </Type>
    </Child>
</Type>

选择这两个元素

<ID/>
<Name>FIND ME</Name>

因此,在您的情况下,产生所需结果的一个XPath表达式为:

//*[not(../*/*)]/Name

<强> II。通用XPath 1.0表达式,当已知最大深度不大于给定数字时,选择具有最大深度的元素:

   //*[count(ancestor::*) >= 9]
   |
    //*[not(//*[count(ancestor::*) >= 9])]
                    [count(ancestor::*) = 8]
   |
    //*[not(//*[count(ancestor::*) >= 8])]
                    [count(ancestor::*) = 7]
   |
    //*[not(//*[count(ancestor::*) >= 7])]
                    [count(ancestor::*) = 6]
   |
    //*[not(//*[count(ancestor::*) >= 6])]
                    [count(ancestor::*) = 5]
   |
    //*[not(//*[count(ancestor::*) >= 5])]
                    [count(ancestor::*) = 4]
   |
    //*[not(//*[count(ancestor::*) >= 4])]
                    [count(ancestor::*) = 3]
   |
    //*[not(//*[count(ancestor::*) >= 3])]
                    [count(ancestor::*) = 2]
   |
    //*[not(//*[count(ancestor::*) >= 2])]
                    [count(ancestor::*) = 1]

   |
    /*[not(//*[count(ancestor::*) >= 1])]

虽然这看起来非常冗长且难以处理,但XML文档的深度通常不超过4-5级,而且这种表达实际上是实用的


<强> III。通用XPath 2.0解决方案:

//*[not(*) and count(ancestor::*) = max(//*/count(ancestor::*))]

答案 1 :(得分:1)

试试这个XPath:

//Type[not(descendant::Type)]/Name