XPath child :: * vs child :: node()

时间:2017-09-08 17:11:52

标签: xml xslt xpath xpath-2.0

我正在进行XSLT转换,我发现了一个我无法回答的有趣问题:

child::*child::node()之间的区别 吗

我想创建一个条件,在其中我将children元素的数量分隔为1,在这种情况下:

<xsl:if test="parent[count(child::*) eq 1])"> 

vs

<xsl:if test="parent[count(child::node()) eq 1])"> 

有什么区别?

2 个答案:

答案 0 :(得分:6)

要了解XPath中child::*child::node()之间的区别,不仅要了解*node()节点测试之间的差异,还要了解elementattribute节点测试之间的差异{3}}轴...

主要节点类型

规则:如果某个轴可以包含元素,则其主节点类型attribute;否则,它是轴可以包含的节点类型。 (例如,child轴的主节点类型element,因为它只能包含属性。)

child::*轴可以包含元素,因此子轴的主节点类型child::node()

每轴节点测试

因此,*child之间的差异是

  • *轴上的element节点测试对所有元素 成功 上下文节点,因为node()节点测试成功主节点类型的所有节点node(),此处),而
  • 所有节点 child节点测试成功 上下文节点,因为所有节点类型child::*节点测试成功。但请注意,并非所有节点类型都可以位于child::node()轴上。以下是七种类型的节点以及它们是否可以出现在子轴上:
    • root :不,根据定义,root是其他节点的子节点。
    • 元素:是
    • text :是
    • 属性:不,属性有自己的轴。
    • namespace :不,命名空间有自己的轴。
    • 处理说明:是
    • 评论:是

因此,#include <iostream> #include <vector> #include <limits> #include <chrono> #include <iomanip> #include <vector> #include <algorithm> struct Data { double x[SIZE_OF_DATA_ARRAY]; }; double workOnData(Data &data) { for (auto i = 0; i < 10; ++i) { data.x[0] -= 0.5 * (data.x[0] - 1); } return data.x[0]; } void runTestSuite() { auto queries = 1000000; Data data; for (auto i = 0; i < queries; ++i) { data.x[0] = i; auto val = workOnData(data); if (val == -357) data.x[0] = 1; } } int main() { std::cout << "sizeof(Data) = " << sizeof(Data) << "\n"; size_t numberOfTests = 99; std::vector<std::chrono::duration<double>> timeMeasurements{numberOfTests}; std::chrono::time_point<std::chrono::system_clock> startTime, endTime; for (auto i = 0; i < numberOfTests; ++i) { startTime = std::chrono::system_clock::now(); runTestSuite(); endTime = std::chrono::system_clock::now(); timeMeasurements[i] = endTime - startTime; } std::sort(timeMeasurements.begin(), timeMeasurements.end()); std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); std::time_t now_c = std::chrono::system_clock::to_time_t(now); std::cout << std::put_time(std::localtime(&now_c), "%F %T") << ": median time = " << timeMeasurements[numberOfTests * 0.5].count() << "s\n"; return 0; } 匹配上下文节点的所有元素子元素,{{1}}匹配所有元素,文本和处理指令子元素上下文节点。

答案 1 :(得分:3)

  

child :: *和child :: node()之间的区别是什么。

引用here

  • *匹配任何元素
  • node()匹配属性节点和根节点
  • 以外的任何节点

所以child::*只匹配子元素和 child::node()匹配除属性和根节点之外的任何子节点。这些可以是七种节点类型中的五种:元素,注释,文本和命名空间节点以及处理指令(see here)。