简体   繁体   English

XPath Select:相对路径不适用于后续同级

[英]XPath Select: Relative Path not working with Following-Sibling

I've seen this question asked many times but in slightly different ways. 我已经多次问过这个问题,但方式略有不同。 Looking at similar examples, there's something I'm still missing. 看类似的例子,我仍然缺少一些东西。

With the information below, I'm trying to do a XPath 1.0 select to get a set of unique customer account values from a XML with accounts. 根据下面的信息, 我正在尝试进行XPath 1.0选择,以从具有帐户的XML中获取一组唯一的客户帐户值 Executing a XSLT with templates, for-each's, and using Muenchian Grouping is not possible. 无法使用带有模板,每个模板的XSLT以及使用Muenchian分组。

I have this XML: 我有这个XML:

<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/Message">
    <Body xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/Message">
        <MessageParts xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/Message">
            <ReportArchive xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/ReportArchive">
                <Report class="entity">
                    <_DocumentHash>d1fd3992e1d6cde8fd06512cea125792</_DocumentHash>
                    <ReportSection class="entity">
                        <Name>AddressBody</Name>
                        <Type>Body</Type>
                        <ReportSectionField class="entity">
                            <Name>CustTable_AccountNum</Name>
                            <Value>0000000001</Value>
                        </ReportSectionField>
                    </ReportSection>
                    <ReportSection class="entity">
                        <Name>AddressBody</Name>
                        <Type>Body</Type>
                        <ReportSectionField class="entity">
                            <Name>CustTable_AccountNum</Name>
                            <Value>0000000001</Value>
                        </ReportSectionField>
                    </ReportSection>
                    <ReportSection class="entity">
                        <Name>AddressBody</Name>
                        <Type>Body</Type>
                        <ReportSectionField class="entity">
                            <Name>CustTable_AccountNum</Name>
                            <Value>0000000002</Value>
                        </ReportSectionField>
                    </ReportSection>
                    <ReportSection class="entity">
                        <Name>AddressBody</Name>
                        <Type>Body</Type>
                        <ReportSectionField class="entity">
                            <Name>CustTable_AccountNum</Name>
                            <Value>0000000003</Value>
                        </ReportSectionField>
                    </ReportSection>
                    <ReportSection class="entity">
                        <Name>AddressBody</Name>
                        <Type>Body</Type>
                        <ReportSectionField class="entity">
                            <Name>CustTable_AccountNum</Name>
                            <Value>0000000004</Value>
                        </ReportSectionField>
                    </ReportSection>
                    <ReportSection class="entity">
                        <Name>AddressBody</Name>
                        <Type>Body</Type>
                        <ReportSectionField class="entity">
                            <Name>CustTable_AccountNum</Name>
                            <Value>0000000005</Value>
                        </ReportSectionField>
                    </ReportSection>
                </Report>
            </ReportArchive>
        </MessageParts>
    </Body>
</Envelope>

With this XPath: (//*[local-name()='ReportSectionField'][./*[local-name()='Name'] = 'CustTable_AccountNum']/*[local-name()='Value'])[not(. = following-sibling::*)]/text() 使用此XPath: (//*[local-name()='ReportSectionField'][./*[local-name()='Name'] = 'CustTable_AccountNum']/*[local-name()='Value'])[not(. = following-sibling::*)]/text()

Using "()", my assumption was that the relative path select would create a node-set, and then the "not()" filter part would parse each sibling in the result set and return the unique values. 使用“()”,我的假设是相对路径选择将创建一个节点集,然后“ not()”过滤器部分将解析结果集中的每个同级并返回唯一值。 When I use the "following-sibling" axis this fails, but the "following" axis works. 当我使用“跟随兄弟”轴时,此操作失败,但是“跟随”轴有效。 I don't want to traverse the descendants, so "following" is not the axis I want to use. 我不想遍历后代,因此“跟随”不是我要使用的轴。 What am I missing and can someone help me visualize what's going on? 我想念的是什么,有人可以帮助我了解发生了什么吗?

Some other things to note: - The XPath Compiler is .Net based (1.0) utilized by BizTalk (See this article for the reasons why: XPath and XSLT 2.0 for .NET? ) 其他注意事项:-XPath编译器是基于BizTalk的基于.Net(1.0)的(原因为何,请参阅本文: XPath和XSLT 2.0 for .NET?

XPath addresses the nodes in the source document. XPath解决了源文档中的节点。 So, relative from the selected value element, you would still need to look at the following:: axis, since the other value elements are not siblings. 因此,相对于所选value元素,您仍然需要查看following::轴,因为其他value元素不是同级。

You could adjust the XPath to be a bit more specific when selecting the value elements to compare values against by "jumping up" to the ReportSection element, and then looking at the following-sibling::* that satisfy the same selection criteria to find value elements to compare and filter: 您可以通过选择“跳转”到ReportSection元素,然后查看满足相同选择条件以找到value following-sibling::*元素following-sibling::* ,来选择要比较值的value元素时,将XPath调整得更加具体。要比较和过滤的元素:

//*[local-name() = 'ReportSectionField' and 
      *[local-name() = 'Name' and . = 'CustTable_AccountNum']]/
    *[local-name() = 'Value' and 
      not(. = ../../following-sibling::*/
                *[local-name() = 'ReportSectionField' and  
                    *[local-name() = 'Name' and . = 'CustTable_AccountNum']]/
                  *[local-name() = 'Value']
       )
     ]/text()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM