如何获取XML中包含的最长路径的XPath查询?

时间:2011-05-11 07:16:23

标签: xml sql-server-2008 xpath

我有一个XML值和一个像这样的XPath查询:

XML:

<Firms>
    <Firm id="1" select="1" update="1" insert="1" delete="1">
        <Backoffice select="1" update="1" insert="1" delete="1">
            <Transaction select="1" update="1" insert="1" delete="0">
                <DatePeriod startDate="20110101" endDate="20110505" select="1" update="0" insert="0" delete="0"/>
                <DatePeriod startDate="20100101" endDate="20110101" select="0" update="0" insert="0" delete="0"/>
            </Transaction>
        </Backoffice>
    </Firm>
</Firms>

的XPath:

./Firms/Firm[@id="1"]/Backoffice/Transaction/DatePeriod

我想获取XPath中包含的最长前缀的值

在我的例子中,值为:

<DatePeriod startDate="20110101" endDate="20110505" select="1" update="0" insert="0" delete="0"/>
<DatePeriod startDate="20100101" endDate="20110101" select="0" update="0" insert="0" delete="0"/>

如果我们将XPath更改为

./Firms/Firm[@id="1"]/Backoffice/Client/Account

预期结果应为

<Firms>
    <Firm id="1" select="1" update="1" insert="1" delete="1">
        <Backoffice select="1" update="1" insert="1" delete="0"/>
    </Firm>
</Firms>

让我解释一下发生了什么。 XML描述用户的权限,XPath描述安全上下文(安全对象)。首先,我们尝试找出关于对象(./Firms/Firm[@id="1"]/Backoffice/Client/Account)的确切规则,并检查预期的权限(选择,插入或更新)。如果我们找不到它,我们将转到父级别(./Firms/Firm[@id="1"]/Backoffice/Client)并尝试应用上层规则(如果存在)。等等。最后,我们找到现有级别(./Firms/Firm[@id="1"]/Backoffice)并查看父级规则赋予我们选择,更新但不删除的权限。

有没有办法通过XPath实现此逻辑(对于SQL Server 2008)?

3 个答案:

答案 0 :(得分:2)

XPath只能选择文档中存在的节点,不能更改它们。您的输入包含一个具有子项的BackOffice节点,但您所需的输出显示一个没有子项的BackOffice节点。这意味着节点已被更改,因此无法使用XPath完成 - 它需要XSLT或XQuery。

(顺便说一句,我不知道“最长路径”或“最长前缀”是什么意思。)

答案 1 :(得分:1)

我能想到这样做的唯一方法是通过编程尝试并尝试失败:

  1. 您构建了最具体的XPath表达式(./Firms/Firm[@id="1"]/Backoffice/Client/Account);我们称之为X

  2. 使用X查找匹配的节点;如果你找到了,那么你已经完成了,否则你会去第3步。

  3. 如果你可以通过删除它的最后一部分来概括X,那么就这样做,然后转到第2步;否则您在XML中找不到任何匹配项,并且您可能希望引发错误。

  4. 对于如何使用SQL Server 2008,我无法帮助,抱歉。

答案 2 :(得分:1)

您是否需要在单个XPath查询中执行前缀“匹配”?由于XPath的功能特性,这似乎是不可能的。有条件检查是否存在子结果,但没有条件分支。

另一方面,以编程方式从末尾删除位置步骤,直到非空结果似乎很容易。