我有一个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)?
答案 0 :(得分:2)
XPath只能选择文档中存在的节点,不能更改它们。您的输入包含一个具有子项的BackOffice节点,但您所需的输出显示一个没有子项的BackOffice节点。这意味着节点已被更改,因此无法使用XPath完成 - 它需要XSLT或XQuery。
(顺便说一句,我不知道“最长路径”或“最长前缀”是什么意思。)
答案 1 :(得分:1)
我能想到这样做的唯一方法是通过编程尝试并尝试失败:
您构建了最具体的XPath表达式(./Firms/Firm[@id="1"]/Backoffice/Client/Account
);我们称之为X
使用X
查找匹配的节点;如果你找到了,那么你已经完成了,否则你会去第3步。
如果你可以通过删除它的最后一部分来概括X
,那么就这样做,然后转到第2步;否则您在XML中找不到任何匹配项,并且您可能希望引发错误。
对于如何使用SQL Server 2008,我无法帮助,抱歉。
答案 2 :(得分:1)
您是否需要在单个XPath查询中执行前缀“匹配”?由于XPath的功能特性,这似乎是不可能的。有条件检查是否存在子结果,但没有条件分支。
另一方面,以编程方式从末尾删除位置步骤,直到非空结果似乎很容易。