XPath Select: 相对路径不适用于 Following-Sibling

XPath Select: Relative Path not working with Following-Sibling

这个问题我见过很多次,但方式略有不同。看了类似的例子,我还是有所欠缺。

根据以下信息,我正在尝试执行 XPath 1.0 select 以从 XML 获取一组唯一的客户帐户值与帐户。无法使用模板、for-each 和使用 Muenchian 分组执行 XSLT。

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

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

使用“()”,我的假设是相对路径 select 将创建一个节点集,然后 "not()" 过滤器部分将解析结果集中的每个兄弟节点和 return 唯一值。当我使用 "following-sibling" 轴时失败,但 "following" 轴有效。我不想遍历后代,所以 "following" 不是我想用的轴。我错过了什么,有人可以帮助我想象发生了什么吗?

其他一些注意事项: - BizTalk 使用的 XPath 编译器基于 .Net (1.0)(请参阅本文了解原因:XPath and XSLT 2.0 for .NET?

XPath 寻址源文档中的节点。因此,相对于所选 value 元素,您仍然需要查看 following:: 轴,因为其他 value 元素不是兄弟。

在选择 value 元素以比较 "jumping up" 与 ReportSection 元素的值,然后查看 following-sibling::* 满足相同的选择标准以查找 value 个要比较和筛选的元素:

//*[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()