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()
这个问题我见过很多次,但方式略有不同。看了类似的例子,我还是有所欠缺。
根据以下信息,我正在尝试执行 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()