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

发布于 2024-11-06 12:49:51 字数 1793 浏览 0 评论 0原文

我有一个 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

我想获取 XML 中包含的 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)实现此逻辑?

I have an XML value and an XPath query like this:

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

I want to get values of the longest prefix of XPath, contained in XML.

In my example the values would be:

<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"/>

If we change the XPath to

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

the expected result should be

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

Let me explain what is going on. The XML describes user's privileges, the XPath describes the security context (the securable object). First we try to find out if there is an exact rule about the object (./Firms/Firm[@id="1"]/Backoffice/Client/Account) and check the expected rights (select, insert or update). If we don't find it we go to the parent level (./Firms/Firm[@id="1"]/Backoffice/Client) and try to apply the uplevel rules (if they exist). And so on. Finally we find the existing level (./Firms/Firm[@id="1"]/Backoffice) and see that the parent rule gives us the rights to select, update, but not to delete.

Is there a way to implement this logic via XPath (for SQL Server 2008)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千紇 2024-11-13 12:49:51

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

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

XPath can only select nodes that are present in your document, it cannot change them. Your input contains a BackOffice node that has children, but your desired output shows a BackOffice node with no children. That means the node has been changed, and therefore it can't be done with XPath - it needs XSLT or XQuery.

(By the way, I've no idea what you mean by "longest path" or "longest prefix".)

擦肩而过的背影 2024-11-13 12:49:51

我能想到的唯一方法是以编程方式尝试和失败:

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

  2. 你使用X来查找匹配的节点;如果找到,则完成,否则转到步骤 3。

  3. 如果您可以通过删除 X 的最后一部分来概括 X,则执行此操作并转到步骤 2;如果 找到,则转到步骤 3。否则,您无法在 XML 中找到任何匹配项,并且您可能想引发错误。

抱歉,我无法帮助您了解如何使用 SQL Server 2008 执行此操作。

The only way that I can think of doing this is by programmatically try-and-fail:

  1. you build your most specific XPath expression (./Firms/Firm[@id="1"]/Backoffice/Client/Account); let's call it X

  2. you use X to find matching nodes; if you find any, then you've finished, otherwise you go to step 3.

  3. if you can generalize X by removing the last part of it, then do it and go to step 2; otherwise you can't find any match in your XML, and you probably want to raise an error.

I can't help on how to do this with SQL Server 2008, sorry.

倦话 2024-11-13 12:49:51

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

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

Do you need to do the prefix "matching" in a single XPath query? That seems impossible due to the functional nature of XPath. There are conditionals to check for existence of subresults, but there is no conditional branching.

On the other hand stripping away location steps from the end programatically until there is a non-empty result seems easy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文