XPath 1.0中PaymentDate为nil时替换为AccountingDate的实现方案
I’ve run into similar XPath 1.0 limitations before, so I know how annoying it is when the fancier 2.0+ functions aren’t on the table. Let’s work through this problem step by step:
The Core Approach
Since we can’t use nilled() and boolean(PaymentDate) still returns true for nil-marked nodes, we’ll directly check for the xsi:nil="true" attribute to decide which value to pull.
Working XPath Expressions
Option 1 (Prefix-Assumed)
If your XML parser already maps the xsi prefix to the http://www.w3.org/2001/XMLSchema-instance namespace (which most do for valid XML), use this clean version:
(PaymentDate[not(@xsi:nil='true')] | AccountingDate[PaymentDate/@xsi:nil='true'])/text()
Option 2 (Namespace-Agnostic)
If you can’t rely on the xsi prefix being configured, target the nil attribute directly using its namespace URI and local name:
( PaymentDate[not(@*[local-name()='nil' and namespace-uri()='http://www.w3.org/2001/XMLSchema-instance']='true')] | AccountingDate[PaymentDate/@*[local-name()='nil' and namespace-uri()='http://www.w3.org/2001/XMLSchema-instance']='true'] )/text()
How It Works
For each EventDetails node:
- The first segment selects the
PaymentDatenode only if it doesn’t have thexsi:nil="true"attribute, then extracts its text value. - The second segment selects the
AccountingDatenode only if the correspondingPaymentDateis marked nil, then extracts its text value. - The
|operator combines these node sets, and since eachEventDetailswill match exactly one condition, you’ll get the correct value per event.
Testing with Your XML
- For the first
EventDetails:PaymentDatehas no nil attribute, so you’ll get2017-01-31. - For the second
EventDetails:PaymentDateis marked nil, so you’ll fall back toAccountingDate’s value2017-01-01.
内容的提问来源于stack exchange,提问作者user9267428

