XSLT: how to pass different prefix values for Node and its feilds - xslt-2.0

I have a requirement where Nodes have a different prefix value where as fields under them has a different prefix, how to achieve this using XSLT. I have attached sample input and expected its output. Can you please advise.
I am expecting nodes have prebix "cac" and its fields as "cbc" and also replace namespace ns2 with r1 prefix.
Input:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:StandardBusinessDoc xmlns:ns0="http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader">
<ns1:Invoice xmlns:ns1="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<ns1:CustomizationID>urn:cen.eu:en131:2017#compliant#urn:fdc:peppol.eu:2017:pocc:billing:3.0</ns1:CustomizationID>
<ns1:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ns1:ProfileID>
<ns1:ID>80160238</ns1:ID>
<ns1:BuyerReference>202208_604</ns1:BuyerReference>
<ns1:BillingReference>
<ns1:InvoiceDocumentReference>
<ns1:ID>test</ns1:ID>
<ns1:IssueDate>2022-09-28</ns1:IssueDate>
</ns1:InvoiceDocumentReference>
</ns1:BillingReference>
<ns1:AdditionalDocumentReference>
<ns1:ID>06AB87FD6E1E1EED96F1653A13ADC23</ns1:ID>
<ns1:DocumentDescription>SupplierUID</ns1:DocumentDescription>
</ns1:AdditionalDocumentReference>
<ns1:AdditionalDocumentReference>
<ns1:ID>2M</ns1:ID>
<ns1:DocumentDescription>Series</ns1:DocumentDescription>
</ns1:AdditionalDocumentReference>
<ns2:Classification xmlns:ns2="rl:rl-einvoicing">
<ns2:Line>
<ns2:ID>000010</ns2:ID>
<ns2:VatCategory>
<ns2:VatRate>24</ns2:VatRate>
<ns2:IncomeClassification>
<ns2:Category>category1_2</ns2:Category>
<ns2:Type>E3_561_005</ns2:Type>
<ns2:Amount>112.33</ns2:Amount>
</ns2:IncomeClassification>
</ns2:VatCategory>
</ns2:Line>
</ns2:Classification>
</ns0:StandardBusinessDoc>
Expected Output:
<?xml-model href="http://www.unece.org/fileadmin/DAM/cefact/namespaces/StandardBusinessDocumentHeader/StandardBusinessDocumentHeader.xsd" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<StandardBusinessDoc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader http://www.unece.org/fileadmin/DAM/cefact/namespaces/StandardBusinessDocumentHeader/StandardBusinessDocumentHeader.xsd" xmlns:rl="rl:rl-einvoicing" xmlns="http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader">
<Invoice xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<cbc:CustomizationID>urn:cen.eu:en131:2017#compliant#urn:fdc:peppol.eu:2017:pocc:billing:3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>80160238</cbc:ID>
<cbc:BuyerReference>202208_604</cbc:BuyerReference>
<cac:BillingReference>
<cac:InvoiceDocumentReference>
<cbc:ID>test</cbc:ID>
<cbc:IssueDate>2022-09-28</cbc:IssueDate>
</cac:InvoiceDocumentReference>
</cac:BillingReference>
<cac:AdditionalDocumentReference>
<cbc:ID>06AB87FD6E1E1EED96F1653A13ADC23</cbc:ID>
<cbc:DocumentDescription>SupplierUID</cbc:DocumentDescription>
</cac:AdditionalDocumentReference>
<cac:AdditionalDocumentReference>
<cbc:ID>2Μ</cbc:ID>
<cbc:DocumentDescription>Series</cbc:DocumentDescription>
</cac:AdditionalDocumentReference>
<rl:Classification>
<rl:Line>
<rl:ID>000010</rl:ID>
<rl:VatCategory>
<rl:VatRate>24</rl:VatRate>
<rl:IncomeClassification>
<rl:Category>category1_2</rl:Category>
<rl:Type>E3_561_005</rl:Type>
<rl:Amount>112.33</rl:Amount>
</rl:IncomeClassification>
</rl:VatCategory>
</rl:Line>
</rl:Classification>
</StandardBusinessDoc>

Related

My F# code cannot read XML using XSD template

I want to parse data from my bank account in F# that are provided in XML. I have an XSD schema of a statement.
My code reads the schema but it is not able to read the structure. I see the content in XML in data.XElement, however, data.AccountStatement property does not exist. The code goes to None option and then the application crashes. Do you have any idea why the code loads the schema but cannot work with data in XML?
open FSharp.Data
let TestAddress = "TESTADDRESS"
let dateRegex = #"\d{1,2}[.]\d{1,2}[.]\d{4}";
type BankTransactionList = XmlProvider<Schema="Schemas/IBSchema.xsd">
let data = BankTransactionList.Parse(Http.RequestString(TestAddress))
[<EntryPoint>]
let main argv =
let AccountStatement =
match data.AccountStatement with
| Some v -> Some v
| None -> None //code goes here
let TransactionList =
match AccountStatement.Value.TransactionList with //and crashes here
| Some v -> Some v
| None -> None
for transaction in TransactionList.Value.Transactions do
printf "%s" transaction.Column22.Value
0 // return an integer exit code
I am developing in .Net Core 2.1. You can see the anonymized example of XML data below.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AccountStatement>
<Info>
<accountId>X</accountId>
<bankId>X</bankId>
<currency>CZK</currency>
<iban>X</iban>
<bic>X</bic>
<openingBalance>X</openingBalance>
<closingBalance>X</closingBalance>
<dateStart>X</dateStart>
<dateEnd>X</dateEnd>
<idFrom>X</idFrom>
<idTo>16663326563</idTo>
</Info>
<TransactionList>
<Transaction>
<column_22 name="ID pohybu" id="22">0</column_22>
<column_0 name="Datum" id="0">2018-08-25+02:00</column_0>
<column_1 name="Objem" id="1">0</column_1>
<column_14 name="Měna" id="14">CZK</column_14>
<column_5 name="VS" id="5">1023</column_5>
<column_16 name="Zpráva pro příjemce" id="16">Message</column_16>
<column_8 name="Typ" id="8">Platba kartou</column_8>
<column_9 name="Provedl" id="9">Pešík, Jiří</column_9>
<column_17 name="ID pokynu" id="17">0</column_17>
</Transaction>
</TransactionList>
</AccountStatement>
I think the issue is that the schema requires the namespace: "http://www.fio.cz/IBSchema".
Adding the namespace in the document should solve the issue:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AccountStatement xmlns="http://www.fio.cz/IBSchema">
<Info>
<accountId>X</accountId>
<bankId>X</bankId>
<currency>CZK</currency>
<iban>X</iban>
<bic>X</bic>
<openingBalance>0</openingBalance>
<closingBalance>0</closingBalance>
<dateStart>2000-01-01</dateStart>
<dateEnd>2001-01-01</dateEnd>
<idFrom>0</idFrom>
<idTo>16663326563</idTo>
</Info>
<TransactionList>
<Transaction>
<column_22 name="ID pohybu" id="22">0</column_22>
<column_0 name="Datum" id="0">2018-08-25+02:00</column_0>
<column_1 name="Objem" id="1">0</column_1>
<column_14 name="Měna" id="14">CZK</column_14>
<column_5 name="VS" id="5">1023</column_5>
<column_16 name="Zpráva pro příjemce" id="16">Message</column_16>
<column_8 name="Typ" id="8">Platba kartou</column_8>
<column_9 name="Provedl" id="9">Pešík, Jiří</column_9>
<column_17 name="ID pokynu" id="17">0</column_17>
</Transaction>
</TransactionList>
</AccountStatement>
I hope your bank is not producing documents lacking the namespace and a schema requiring it.

AntSCript to extract xml tag having specific matching string in attribute value from xml file

I have and XML file as below
<sca:composite xmlns:sca="http://www.osoa.org/xmlns/sca/1.0" xmlns:atleastonce="http://www.tibco.com/wrm/policy/atleastonce" xmlns:common="http://xsd.tns.tibco.com/n2/models/common" xmlns:compositeext="http://schemas.tibco.com/amx/3.0/compositeext" xmlns:jdbc="http://xsd.tns.tibco.com/amf/models/sharedresource/jdbc" xmlns:pbu="http://www.tibco.com/wrm/policy/pbu" xmlns:pfe="http://xsd.tns.tibco.com/n2/models/pfe/1.0" xmlns:scact="http://xsd.tns.tibco.com/amf/models/sca/componentType" xmlns:scaext="http://xsd.tns.tibco.com/amf/models/sca/extensions" xmlns:service="http://xsd.tns.tibco.com/bx/amx/model" xmlns:smtp="http://xsd.tns.tibco.com/amf/models/sharedresource/smtp" xmlns:soapbt="http://xsd.tns.tibco.com/amf/models/sca/binding/soap" xmlns:startservicefirst="http://www.tibco.com/wrm/policy/startservicefirst" xmlns:threading="http://www.tibco.com/wrm/policy/threading" xmlns:transactedoneway="http://www.tibco.com/wrm/policy/transactedoneway" xmlns:webapp="http://xsd.tns.tibco.com/amf/models/sca/implementationtype/webapp" xmlns:wrm="http://www.tibco.com/wrm" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" compositeext:formatVersion="2" compositeext:version="1.0.0.20180112132229840" name="za.co.rmb.dealamendmentsmaintenance" targetNamespace="http://www.example.com/za.co.rmb.dealamendmentsmaintenance" xmi:id="_4EfRQfeKEeeZRvktH3XIjg" xmi:version="2.0">
<sca:reference multiplicity="0..1" name="WorkListService_Consumer1" promote="dealAmendmentsMaintenanceProcessFlow/WorkListService_Consumer" wiredByImpl="false" xmi:id="_AR2UQPeLEeeZRvktH3XIjg">
<sca:interface.wsdl interface="http://services.brm.n2.tibco.com#wsdl.interface(WorkListService)" scaext:wsdlLocation=".processOut/process/dealAmendmentsMaintenance.xpdl/brm.wsdl" xmi:id="_AR2UQfeLEeeZRvktH3XIjg"/>
</sca:reference>
<sca:reference multiplicity="0..1" name="CreateDailyTasks_Consumer1" promote="dealAmendmentsMaintenanceProcessFlow/CreateDailyTasks_Consumer" wiredByImpl="false" xmi:id="_ATRQkPeLEeeZRvktH3XIjg">
<sca:interface.wsdl interface="http://www.tibco.com/bs3.0/_8uwIINbzEeWTpucOvGErRg#wsdl.interface(CreateDailyTasks)" scaext:wsdlLocation=".processOut/process/dealAmendmentsMaintenance.xpdl/dealAmendments_segregation.wsdl" xmi:id="_ATRQkfeLEeeZRvktH3XIjg"/>
</sca:reference>
</sca:composite>
With ant script i want to extract value in the "interface" attribute under sca:interface, by matching input value in "name" attribute in sca:refernce.
So lets say
if input will be : WorkListService_Consumer1
Expected Output : http://services.brm.n2.tibco.com#wsdl.interface(WorkListService)
Similarly, if
input will be : CreateDailyTasks_Consumer1
Expected Output : http://www.tibco.com/bs3.0/_8uwIINbzEeWTpucOvGErRg#wsdl.interface(CreateDailyTasks)
I tried using various xmltask commands but i am not getting succesfull.
Thanks
Shrijeet Sinha
You almost had the solution, however text() is used to reference the inner text of an XML element, such as <element>This text here</element>. Here is the syntax for referencing an attribute's value:
<xmltask source="xmlfile.xml">
<copy path="sca:composite/sca:reference[#name='${input}']/sca:interface.wsdl/#interface" property="testproperty"/>
</xmltask>

WFS GetFeature output from ArcGIS cannot be parsed with any ol.format.*

A simple ol.format.ogc.filter.bbox works with no problem using Geoserver, and I can parse the output xml as follows:
features = new ol.format.GML3().readFeatures(result);
However; when using the same filter with ArcGIS the output xml cannot be parsed. The results returned by the map server are correct, but the code above parses only the first feature returned. I tried using new ol.format.GML2 which parses the right amount of features but with no geometry, so I think it is not the case. There is a clear difference in the output xmls (see below).
How can I parse the second xml (returned by ArcGIS) using OpenLayers 3? Is there a way to change the output xml in ArcGIS?
Geoserver:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:FeatureCollection numberOfFeatures="2" timeStamp="2016-09-02T15:19:25.157Z" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:rkms="http://rkms" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://mapserver/geoserver/wfs?service=WFS&version=1.1.0&request=DescribeFeatureType&typeName=rkms%3AMyLayer http://www.opengis.net/wfs http://mapserver/geoserver/schemas/wfs/1.1.0/wfs.xsd">
<gml:boundedBy>
<gml:Envelope srsDimension="2" srsName="http://www.opengis.net/gml/srs/epsg.xml#3857">
<gml:lowerCorner>6290152.654765377 2551363.9791194764</gml:lowerCorner>
<gml:upperCorner>6290408.655102356 2551457.2361871097</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<gml:featureMembers>
<rkms:MyLayer gml:id="MyLayer.4727">
<gml:boundedBy>
<gml:Envelope srsDimension="2" srsName="http://www.opengis.net/gml/srs/epsg.xml#3857">
<gml:lowerCorner>6290152.654765377 2551363.9791194764</gml:lowerCorner>
<gml:upperCorner>6290152.654765377 2551363.9791194764</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<rkms:fid>6319.0</rkms:fid>
<rkms:uwi>FAHUD WDW-5H1</rkms:uwi>
<rkms:display_class>General#0x0048</rkms:display_class>
<rkms:label>FAHUD WDW-5H1</rkms:label>
<rkms:the_geom>
<gml:Point srsDimension="2" srsName="http://www.opengis.net/gml/srs/epsg.xml#3857">
<gml:pos>6290152.654765377 2551363.9791194764</gml:pos>
</gml:Point>
</rkms:the_geom>
<rkms:well_status>completed</rkms:well_status>
<rkms:show_type>unknown</rkms:show_type>
</rkms:MyLayer>
<rkms:MyLayer gml:id="MyLayer.21732">
<gml:boundedBy>
<gml:Envelope srsDimension="2" srsName="http://www.opengis.net/gml/srs/epsg.xml#3857">
<gml:lowerCorner>6290408.655102356 2551457.2361871097</gml:lowerCorner>
<gml:upperCorner>6290408.655102356 2551457.2361871097</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<rkms:fid>23325.0</rkms:fid>
<rkms:uwi>FAHUD WDW-7H1</rkms:uwi>
<rkms:display_class>General#0x0048</rkms:display_class>
<rkms:label>FAHUD WDW-7H1</rkms:label>
<rkms:the_geom>
<gml:Point srsDimension="2" srsName="http://www.opengis.net/gml/srs/epsg.xml#3857">
<gml:pos>6290408.655102356 2551457.2361871097</gml:pos>
</gml:Point>
</rkms:the_geom>
<rkms:well_status>producing</rkms:well_status>
<rkms:show_type>unknown</rkms:show_type>
</rkms:MyLayer>
</gml:featureMembers>
ArcGIS:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:FeatureCollection xmlns:MyLayer="http://mapserver/arcgis/services/MyLayer/MapServer/WFSServer" xmlns:gml="http://www.opengis.net/gml" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://mapserver/arcgis/services/MyLayer/MapServer/WFSServer http://mapserver/arcgis/services/MyLayer/MapServer/WFSServer?request=DescribeFeatureType%26version=1.1.0%26typename=WellHole http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/base/gml.xsd">
<gml:boundedBy>
<gml:Envelope srsName="EPSG:3857">
<gml:lowerCorner>6280561.8275626749 2548148.676770444</gml:lowerCorner>
<gml:upperCorner>6289533.3190469407 2559799.8122104518</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<gml:featureMember>
<MyLayer:WellHole gml:id="F662__369">
<MyLayer:OBJECTID>369</MyLayer:OBJECTID>
<MyLayer:Well_Number>0</MyLayer:Well_Number>
<MyLayer:Hole_Number>0</MyLayer:Hole_Number>
<MyLayer:SHAPE>
<gml:Point>
<gml:pos>6288892.4079840938 2550358.0037752441</gml:pos>
</gml:Point>
</MyLayer:SHAPE>
</MyLayer:WellHole>
</gml:featureMember>
<gml:featureMember>
<MyLayer:WellHole gml:id="F662__400">
<MyLayer:OBJECTID>400</MyLayer:OBJECTID>
<MyLayer:Well_Number>0</MyLayer:Well_Number>
<MyLayer:Hole_Number>0</MyLayer:Hole_Number>
<MyLayer:SHAPE>
<gml:Point>
<gml:pos>6288797.9203164754 2550567.9331951309</gml:pos>
</gml:Point>
</MyLayer:SHAPE>
</MyLayer:WellHole>
</gml:featureMember>
</wfs:FeatureCollection>
Use ol.format.WFS that should work.

Xml parsing in rails

I have this XML data:
<?xml version="1.0" encoding="UTF-8"?>
<responseParam>
<RESULT>-1</RESULT>
<ERROR_CODE>509</ERROR_CODE>
</responseParam>
How can I fetch the value of error code only?
I have tried this :
result = Net::HTTP.get(URI.parse(otpUrl))
data = Hash.from_xml(result)
puts "#{data['ERROR_CODE']}"
puts data[:ERROR_CODE]
printing only "data" gives me the whole hash. I am not able to get only the value of ERROR_CODE.
Any help ?
you can use Nokigiri here.
suppose this is your error.xml
<?xml version="1.0" encoding="UTF-8"?>
<responseParam>
<RESULT>-1</RESULT>
<ERROR_CODE>509</ERROR_CODE>
</responseParam>
you can do something like:-
#doc = Nokogiri::XML(File.open("error.xml"))
#doc.xpath("//ERROR_CODE")
will give you something like:-
# => ["<ERROR_CODE>509</ERROR_CODE>]"
The Node methods xpath and css actually return a NodeSet, which acts very much like an array, and contains matching nodes from the document.

Problem with BizTalk multi-input map

I have a map that takes 2 input messages, like this:
<ns0:Root>
<InputMessagePart_0>
<root>
<Indicator>1</Indicator>
<NewValue>AAA</NewValue>
</root>
<InputMessagePart_0>
<InputMessagePart_1>
<root>
<Value>BBB</Value>
</root>
<InputMessagePart_1>
</ns0:Root>
(Lots of the nodes are not shown for clarity)
The ouput message looks like this:
<Root>
<Value>AAA</Value>
</Root>
(It's identical to InputMessagePart_1)
If the Indicator is 1, I want Value to be replaced with NewValue. If it's 0, I want Value to stay the same. I used a scripting functoid with code like this:
public string Get_Value(string indicator, string value, string newValue)
{
if(indicator == "1")
{
return newValue;
}
else
{
return value;
}
}
I'm running into problems due to the fact that Value might not actually occur in the original InputMessagePart_1 - if it doesn't, I want to create it. With the script above, even though Indicator is 1, I'm not getting a return string when Value doesn't exist.
Any suggestions?
Updated: I did some further testing by removing the if/then logic and just returned a hard-coded string from the functoid, and I get the same results... it seems that just having the empty input kills the entire functionality of the functoid...
You should want to use the Equal functoid and test whether the value is 1. You'll then feed the result to the input of two functoids:
First, to a Value Mapping functoid, which is connected to the <New Value> tag in the first part of the source schema.
Second, to a Logical Not functoid, which is then connected to another Value Mapping functoid connected to the <Value> tag in the second part of the source schema.
If the <Indicator>; tag does not contain the expected value 1 or is not present in the source message, the Logical Equal functoid will return False, and the second branch of the map will execute.
It doesn't matter whether the Value tag is present in the second part of the source schema. If it is not, either one of the Value Mapping functoids will create it in the destination.
If you definitely need to depend upon the <Indicator> tag, you might want to use the Logical Existence functoid, that returns whether any specified input node appears in the source message.
If all else fails using the mapper, you might try switching to XSLT - see here how to scrape the XSLT out of your existing BTM.
The map that you are after looks straightforward:
<?xml version="1.0" encoding="utf-16"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > .. etc ... whatever you've scraped out
<xsl:output ...
<xsl:template match=...>
<ns1:Root>
<ns1:Value>
<xsl:choose>
<xsl:when test="/ns0:Root/ns0:InputMessagePart_0/ns0:root/ns0:Indicator/text()='1'">
<xsl:value-of select="/ns0:Root/ns0:InputMessagePart_0/ns0:root/ns0:NewValue/text()" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="/ns0:Root/ns0:InputMessagePart_1/ns0:root/ns0:Value/text()" />
</xsl:otherwise>
</xsl:choose>
<ns1:Value>
</ns1:Root>

Resources