Как работать с несколькими десятичными числами при синтаксическом анализе XML с помощью XSLT?

#java #xml #xslt #xml-parsing #xslt-1.0

#java #xml #xslt #xml-синтаксический анализ #xslt-1.0

Вопрос:

Я работаю в розничной торговле, где у нас есть MaxLineStatus, который подразумевает текущий статус заказа, размещенного клиентом. В рамках этого процесса у меня есть XML, который необходимо передать в XSLT для преобразования. Мой XSLT имеет проверку MaxLineStatus < 3700.7777, а значение MaxLineStatus передается как 3200.200.100 во входном xml. В идеальном сценарии 3200.200.100 меньше 3700.7777, и в свою очередь он должен соответствовать критериям и заполнять узел OrderLine.

Всякий раз, когда я передаю 3200.200 вместо 3200.200.100 в xml, я получаю желаемый результат. Я даже пытался сохранить значение xslt в некоторой переменной, а затем сравнить значение, но оно все равно не работает.

Я сравниваю значение в приведенном ниже фрагменте кода:

 <xsl:attribute name="OrderLineCount"><xsl:value-of select="count(./OrderLine[(@MaxLineStatus amp;< 3700.7777) and (@MaxLineStatus!='3200.150') and (@MaxLineStatus!='1400')])" /></xsl:attribute>
 

Спасибо за помощь и извините за публикацию xml и xslt таким образом. Я столкнулся с некоторой проблемой с тем же отступом. Прошу прощения.

XML:

 <OrderRelease APIName="sendReleaseModificationUpdateToILS" CarrierServiceCode="" DeliveryMethod="DEL" DocumentType="0003" EnterpriseCode="RETAIL" MFLocationId="70" NotificationType=" " OrderDate="20190410T06:49:07" OrderHeaderKey="2019041006490764562203" OrderLineCount="1" PriorityCode="" PriorityNumber="0" ProNumber="" ReleaseNo="1" RewardZoneIndicator="N" SCAC="" SalesOrderNo="1119100622586" ShipNode="BBY_9034" ShippingType="" WorkOrderKey="2019041006493464562225"><Shipnode Localecode="en_US_CST" NodeType="DDC" ReceiptProcessingTime="60.00" ShipNode="BBY_9034"><Extn FulfilmentDateBufferTime="0" LocationID="9034" MFLocationId="70" MobileSAS="N" /></Shipnode><Order CarrierServiceCode="" CustomerEMailID="RACHAKONDA.SATYASRINIVAS@BESTBUY.COM" DocumentType="0001" DraftOrderFlag="N" EnterpriseCode="RETAIL" MaxOrderStatus="3200.200.100" MinOrderStatus="1100.100" NotificationType=" " OrderDate="20190410T06:49:07" OrderHeaderKey="2019041006490764562203" OrderNo="1119100622586" OrderPurpose="" PriorityCode="" PriorityNumber="0" ReturnOrderHeaderKeyForExchange=" " SCAC="" SellerOrganizationCode="BBY_281" ShipNode=" " Status="Partially Awaiting Pickup Date" isHistory="N" /><OrderLine CarrierServiceCode="" ConditionVariable1="" ConditionVariable2="" DeliveryMethod="DEL" DependentOnLineKey=" " DerivedFromOrderHeaderKey="2018012921180556404483" DerivedFromOrderLineKey="2018012921180556404485" FulfillmentType="DELIVERY" HasDerivedChild="" LineType="RETURN" MaxLineStatus="3200.200.100" MaxLineStatusDesc="Awaiting Pickup Date" MinLineStatus="3200.200.100" MinLineStatusDesc="Awaiting Pickup Date" OpenQty="1" OrderLineKey="2019041006490764562204" OrderedQty="1" PrimeLineNo="1" ProcureFromNode="" PromisedApptEndDate="20190413T19:00:00" PromisedApptStartDate="20190413T07:00:00" SCAC="" ShipNode="BBY_9034" ShipToKey=" " Status="Awaiting Pickup Date" SubLineNo="1"><Extn ExpectedShipDate="20190410T00:00:00" StreetDate="19000101T00:00:00"><EOMSOrderLineList><EOMSOrderLine ExpectedApptEndDate="20190413T19:00:00" ExpectedApptStartDate="20190413T07:00:00" HingeSettings="" LineShipNodeWMS="WMS" OrderLineKey="2019041006490764562204" SellingStoreId="281" /></EOMSOrderLineList></Extn><Item CustomerItem="3519796" CustomerItemDesc="NINTENDO DS UNIVERSAL GAME SELECTOR CASE" ItemID="1640461" ManufacturerItem="52LB5D" ProductClass="" ProductLine="9.99.224" UnitOfMeasure="EACH" /><Notes NumberOfNotes="0" /><ParentOrderLineRelationships /></OrderLine></OrderRelease>
 

XSLT:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" /><xsl:template match="/OrderRelease"><xsl:copy><xsl:copy-of select="@*" /><xsl:attribute name="MFLocationId"><xsl:value-of select="./Shipnode/Extn/@MFLocationId" /></xsl:attribute><Extn><xsl:attribute name="ReleaseSeqNo"><xsl:value-of select="./Extn/@ReleaseSeqNo" /></xsl:attribute></Extn><xsl:attribute name="OrderLineCount"><xsl:value-of select="count(./OrderLine[(@MaxLineStatus amp;< 3700.7777) and (@MaxLineStatus!='3200.150') and (@MaxLineStatus!='1400')])" /></xsl:attribute><xsl:for-each select="./OrderLine[(@MaxLineStatus amp;< 3700.7777) and (@MaxLineStatus!='3200.150') and (@MaxLineStatus!='1400')]"><OrderLine><xsl:copy-of select="./@*" /><xsl:copy-of select="./OrderLineInvAttRequest" /><Item><xsl:copy-of select="./Item/@*" /><Extn><xsl:attribute name="BrandItemID"><xsl:value-of select="./Item/@CustomerItem" /></xsl:attribute></Extn></Item><Notes><xsl:copy-of select="./Notes/*" /></Notes><ParentOrderLineRelationships><xsl:copy-of select="./ParentOrderLineRelationships/*" /></ParentOrderLineRelationships><Extn><xsl:copy-of select="./Extn/*" /></Extn></OrderLine></xsl:for-each><Notes><xsl:for-each select="./Notes/Note"><xsl:copy-of select="current()" /></xsl:for-each></Notes><Order><xsl:attribute name="OrderPurpose"><xsl:value-of select="./Order/@OrderPurpose" /></xsl:attribute><xsl:attribute name="ReturnOrderHeaderKeyForExchange"><xsl:value-of select="./Order/@ReturnOrderHeaderKeyForExchange" /></xsl:attribute><xsl:attribute name="CustomerEMailID"><xsl:value-of select="./Order/@CustomerEMailID" /></xsl:attribute><xsl:attribute name="SellerOrganizationCode"><xsl:value-of select="./Order/@SellerOrganizationCode" /></xsl:attribute><Extn><xsl:attribute name="BillingPhoneNo"><xsl:value-of select="./Order/Extn/@BillingPhoneNo" /></xsl:attribute></Extn></Order><xsl:copy-of select="./PersonInfoShipTo" /></xsl:copy></xsl:template>
 

Фактический результат:

 <OrderRelease APIName="sendReleaseModificationUpdateToILS" CarrierServiceCode="" DeliveryMethod="DEL" DocumentType="0003" EnterpriseCode="RETAIL" MFLocationId="70" NotificationType=" " OrderDate="20190410T06:49:07" OrderHeaderKey="2019041006490764562203" OrderLineCount="1" PriorityCode="" PriorityNumber="0" ProNumber="" ReleaseNo="1" RewardZoneIndicator="N" SCAC="" SalesOrderNo="1119100622586" ShipNode="BBY_9034" ShippingType="" WorkOrderKey="2019041006493464562225"><Extn ReleaseSeqNo="" /><Notes></Notes><Order OrderPurpose="" ReturnOrderHeaderKeyForExchange=" " CustomerEMailID="RACHAKONDA.SATYASRINIVAS@BESTBUY.COM" SellerOrganizationCode="BBY_281"><Extn BillingPhoneNo="" /></Order></OrderRelease>
 

Ожидаемый результат:

 <OrderRelease APIName="sendReleaseModificationUpdateToILS" CarrierServiceCode="" DeliveryMethod="DEL" DocumentType="0003" EnterpriseCode="RETAIL" MFLocationId="70" NotificationType=" " OrderDate="20190410T06:49:07" OrderHeaderKey="2019041006490764562203" OrderLineCount="1" PriorityCode="" PriorityNumber="0" ProNumber="" ReleaseNo="1" RewardZoneIndicator="N" SCAC="" SalesOrderNo="1119100622586" ShipNode="BBY_9034" ShippingType="" WorkOrderKey="2019041006493464562225"><Extn ReleaseSeqNo="" /><OrderLine CarrierServiceCode="" ConditionVariable1="" ConditionVariable2="" DeliveryMethod="DEL" DependentOnLineKey=" " DerivedFromOrderHeaderKey="2018012921180556404483" DerivedFromOrderLineKey="2018012921180556404485" FulfillmentType="DELIVERY" HasDerivedChild="" LineType="RETURN" MaxLineStatus="3200.200.100" MaxLineStatusDesc="Awaiting Pickup Date" MinLineStatus="3200.200.100" MinLineStatusDesc="Awaiting Pickup Date" OpenQty="1" OrderLineKey="2019041006490764562204" OrderedQty="1" PrimeLineNo="1" ProcureFromNode="" PromisedApptEndDate="20190413T19:00:00" PromisedApptStartDate="20190413T07:00:00" SCAC="" ShipNode="BBY_9034" ShipToKey=" " Status="Awaiting Pickup Date" SubLineNo="1"><Item CustomerItem="3519796" CustomerItemDesc="NINTENDO DS UNIVERSAL GAME SELECTOR CASE" ItemID="1640461" ManufacturerItem="52LB5D" ProductClass="" ProductLine="9.99.224" UnitOfMeasure="EACH"><Extn BrandItemID="3519796" /></Item><Notes></Notes><ParentOrderLineRelationships></ParentOrderLineRelationships><Extn><EOMSOrderLineList><EOMSOrderLine ExpectedApptEndDate="20190413T19:00:00" ExpectedApptStartDate="20190413T07:00:00" HingeSettings="" LineShipNodeWMS="WMS" OrderLineKey="2019041006490764562204" SellingStoreId="281" /></EOMSOrderLineList></Extn></OrderLine><Notes></Notes><Order OrderPurpose="" ReturnOrderHeaderKeyForExchange=" " CustomerEMailID="RACHAKONDA.SATYASRINIVAS@BESTBUY.COM" SellerOrganizationCode="BBY_281"><Extn BillingPhoneNo="" /></Order></OrderRelease>
 

Комментарии:

1. Не существует такого понятия, как «несколько десятичных знаков». Строка «3200.200.100» не является числом. Если вы хотите сравнить его с числом, вы должны сначала преобразовать его в число. Пожалуйста, объясните логику , с помощью которой это должно быть сделано.

2. @michael.hor257k XML будет иметь значение только в виде строки. Я ищу подход, с помощью которого этого можно достичь. Мне нужно сравнить статус XSLT (3700.7777) с XML. У вас есть какие-либо идеи по этому поводу?

3. Было бы полезно, если бы вы могли отформатировать свой XML для удобства чтения.

4. Нет, потому что я не понимаю логики, по которой «3200.200.100» меньше 3700.7777. Почему это меньше? Вы даете нам только один пример и произвольный результат. Вместо этого дайте нам правило.

Ответ №1:

В XSLT 1.0 единственный способ сравнить строки для < > отношений и — это сортировка; операторы < and > всегда преобразуются в числа (и если значение не может быть преобразовано в число, оно обрабатывается как NaN).

В идеале переходите к более поздней версии XSLT (1.0 становится ОЧЕНЬ устаревшим).

Если вы не можете этого сделать, то это будет сложный обходной путь. Три возможных подхода:

(a) найдите какой-нибудь способ преобразования этих «десятичных десятичных» значений в числа, которые сортируются правильно. (например, дополните каждый компонент стандартным количеством цифр, затем удалите точки).

(b) отсортируйте значения, выделите порядковые номера и проверьте, удовлетворяет ли значение соответствующему условию, просмотрев порядковые номера.

(c) вызовите функцию расширения на внешнем языке, таком как Java, для выполнения сравнения.