XSLT 2.0 remove element only from first record - xslt-1.0

I have placed my XSLT code in below (click below link)
code
My expected output is :
<InputParameters>
<nstrgmpr:P_INSTALL_BASE_STG>
<nstrgmpr:P_INSTALL_BASE_STG_ITEM>
<nstrgmpr:ORIG_SYS_INSTANCE_REF>100000006534645</nstrgmpr:ORIG_SYS_INSTANCE_REF>
<nstrgmpr:ITEM_NUMBER>9W0000365-1002-M</nstrgmpr:ITEM_NUMBER>
<nstrgmpr:FULFILMENT_LINE_ID>300000008528224</nstrgmpr:FULFILMENT_LINE_ID>
<nstrgmpr:IB_RECORD_COUNT>3</nstrgmpr:IB_RECORD_COUNT>
</nstrgmpr:P_INSTALL_BASE_STG_ITEM>
<nstrgmpr:P_INSTALL_BASE_STG_ITEM>
<nstrgmpr:ORIG_SYS_INSTANCE_REF>100000006534647</nstrgmpr:ORIG_SYS_INSTANCE_REF>
<nstrgmpr:ITEM_NUMBER>9W0000328</nstrgmpr:ITEM_NUMBER>
<nstrgmpr:ORIG_SYS_PARENT_INSTANCE_REF>100000006534645</nstrgmpr:ORIG_SYS_PARENT_INSTANCE_REF>
<nstrgmpr:RELATIONSHIP_TYPE>Component Of</nstrgmpr:RELATIONSHIP_TYPE>
<nstrgmpr:FULFILMENT_LINE_ID>300000008528229</nstrgmpr:FULFILMENT_LINE_ID>
<nstrgmpr:IB_RECORD_COUNT>3</nstrgmpr:IB_RECORD_COUNT>
</nstrgmpr:P_INSTALL_BASE_STG_ITEM>
<nstrgmpr:P_INSTALL_BASE_STG_ITEM>
<nstrgmpr:ORIG_SYS_INSTANCE_REF>100000006534648</nstrgmpr:ORIG_SYS_INSTANCE_REF>
<nstrgmpr:ITEM_NUMBER>9W0000327</nstrgmpr:ITEM_NUMBER>
<nstrgmpr:ORIG_SYS_PARENT_INSTANCE_REF>100000006534645</nstrgmpr:ORIG_SYS_PARENT_INSTANCE_REF>
<nstrgmpr:RELATIONSHIP_TYPE>Component Of</nstrgmpr:RELATIONSHIP_TYPE>
<nstrgmpr:FULFILMENT_LINE_ID>300000008528239</nstrgmpr:FULFILMENT_LINE_ID>
<nstrgmpr:IB_RECORD_COUNT>3</nstrgmpr:IB_RECORD_COUNT>
</nstrgmpr:P_INSTALL_BASE_STG_ITEM>
</nstrgmpr:P_INSTALL_BASE_STG>
</InputParameters>
i.e. Remove below elements only in first record but retain in others
<nstrgmpr:ORIG_SYS_PARENT_INSTANCE_REF/>
<nstrgmpr:RELATIONSHIP_TYPE/>

Related

Open Refine: Exporting nested XML with templating

I have a question regarding the templating option for XML in Open Refine. Is it possible to export data from two columns in a nested XML-structure, if both columns contain multiple values, that need to be split first?
Here's an example to illustrate better what I mean. My columns look like this:
Column1
Column2
https://d-nb.info/gnd/119119110;https://d-nb.info/gnd/118529889
Grützner, Eduard von;Elisabeth II., Großbritannien, Königin
https://d-nb.info/gnd/1037554086;https://d-nb.info/gnd/1245873660
Müller, Jakob;Meier, Anina
Each value separated by semicolon in Column1 has a corresponding value in Column2 in the right order and my desired output would look like this:
<rootElement>
<recordRootElement>
...
<edm:Agent rdf:about="https://d-nb.info/gnd/119119110">
<skos:prefLabel xml:lang="zxx">Grützner, Eduard von</skos:prefLabel>
</edm:Agent>
<edm:Agent rdf:about="https://d-nb.info/gnd/118529889">
<skos:prefLabel xml:lang="zxx">Elisabeth II., Großbritannien, Königin</skos:prefLabel>
</edm:Agent>
...
</recordRootElement>
<recordRootElement>
...
<edm:Agent rdf:about="https://d-nb.info/gnd/1037554086">
<skos:prefLabel xml:lang="zxx">Müller, Jakob</skos:prefLabel>
</edm:Agent>
<edm:Agent rdf:about="https://d-nb.info/gnd/1245873660">
<skos:prefLabel xml:lang="zxx">Meier, Anina</skos:prefLabel>
</edm:Agent>
...
</recordRootElement>
<rootElement>
(note: in my initial posting, the position of the root element was not indicated and it looked like this:
<edm:Agent rdf:about="https://d-nb.info/gnd/119119110">
<skos:prefLabel xml:lang="zxx">Grützner, Eduard von</skos:prefLabel>
</edm:Agent>
<edm:Agent rdf:about="https://d-nb.info/gnd/118529889">
<skos:prefLabel xml:lang="zxx">Elisabeth II., Großbritannien, Königin</skos:prefLabel>
</edm:Agent>
)
I managed to split the values separated by ";" for both columns like this
{{forEach(cells["Column1"].value.split(";"),v,"<edm:Agent rdf:about=\""+v+"\">"+"\n"+"</edm:Agent>")}}
{{forEach(cells["Column2"].value.split(";"),v,"<skos:prefLabel xml:lang=\"zxx\">"+v+"</skos:prefLabel>")}}
but I can't find out how to nest the splitted skos:prefLabel into the edm:Agent element. Is that even possible? If not, I would work with seperate columns or another workaround, but I wanted to make sure, if there's a more direct way before.
Thank you!
Kristina
I am going to expand the answer from RolfBly using the Templating Exporter from OpenRefine.
I do have the following assumptions:
There is some other column left of Column1 acting as record identifying column (see first screenshot).
The columns actually have some proper names
The columns URI and Name are the only columns with multiple values. Otherwise we might produce empty XML elements with the following recipe.
We will use the information about records available via GREL to determine whether to write a <recordRootElement> or not.
Recipe:
Split first Name and then URI on the separator ";" via "Edit cells" => "Split multi-valued cells".
Go to "Export" => "Templating..."
In the prefix field use the value
<?xml version="1.0" encoding="utf-8"?>
<rootElement>
Please note that I skipped the namespace imports for edm, skos, rdf and xml.
In the row template field use the value:
{{if(row.index - row.record.fromRowIndex == 0, '<recordRootElement>', '')}}
<edm:Agent rdf:about="{{escape(cells['URI'].value, 'xml')}}">
<skos:prefLabel xml:lang="zxx">{{escape(cells['Name'].value, 'xml')}}</skos:prefLabel>
</edm:Agent>
{{if(row.index - row.record.fromRowIndex == row.record.rowCount - 1, '</recordRootElement>', '')}}
The row separator field should just contain a linebreak.
In the suffix field use the value:
</rootElement>
Disclaimer: If you're keen on using only OpenRefine, this won't be the answer you were hoping for. There may be ways in OR that I don't know of. That said, here's how I would do it.
Edit The trick is to keep URL and literal side by side on one line. b2m's answer below does just that: go from right to left splitting, not from left to right. You can then skip steps 2 and 3, to get the result in the image.
split each column into 2 columns by separator ;. You'll get 4 columns, 1 and 3 belong together, and 2 and 4 belong together. I'm assuming this will be the case consistently in your data.
export 1 and 3 to a file, and export 2 and 4 to another file, of any convenient format, using the custom tabular exporter.
concatenate those two files into one single file using an editor (I use Notepad++), or any other method you may prefer. Several ways to Rome here. Result in OR would be something like this.
You then have all sorts of options to put text strings in front, between and after your two columns.
In OR, you could use transform on column URL to build your XML using the below code
(note the \n for newline, that's probably just a line feed, you may want to use \r\n for carriage return + line feed if you're using Windows).
'<edm:Agent rdf:about="' + value + '">\n<skos:prefLabel xml:lang="zxx">' + cells.Name.value + '</skos:prefLabel>\n</edm:Agent>'
to get your XML in one column, like so
which you can then export using the custom tabular exporter again. Or instead you could use Add column based on this column in a similar manner, if you want to retain your URL column.
You could even do this in the editor without re-importing the file back into OR, but that's beyond the scope of this answer.

Find XML tag which is present several times

I am working with an Oracle database 19c.
I have a table with the blob field "MSG_BODY". This field contains XML's like that:
<Body xmlns = "http://www.finnova.ch/ZV/EHF/021">
<Auftrag>
<Auftragsinformation>
<Auftragsidentifikation>
<AUF_LNR>987987987987</AUF_LNR>
<APPL_ID>9999</APPL_ID>
</Auftragsidentifikation>
<Auftragsreferenz>
<EXT_REF>TEST-2020082109574181</EXT_REF>
<EXT_AUF_REF>BA18081508D86B28</EXT_AUF_REF>
<KD_LNR_ERF>901</KD_LNR_ERF>
</Auftragsreferenz>
</Auftragsinformation>
<Zahlungsliste>
<Zahlung>
<Identifikation>
<ZV_ZLG_SYS_LNR>987987987987</ZV_ZLG_SYS_LNR>
<ZV_ZLG_LNR>1</ZV_ZLG_LNR>
</Identifikation>
<Referenz>
<EXT_REF>ABCD654654654</EXT_REF>
<EXT_REF_AUF>XX-XXX 230/99999/1</EXT_REF_AUF>
<EXT_REF_AUF_IB>BA9999988888</EXT_REF_AUF_IB>
<ZLG_INSTR_ID>BA999988886666</ZLG_INSTR_ID>
<MeldungsRef>
<MSG_TX_ID>123123123123</MSG_TX_ID>
<CS_ZLG_TRACK_ID>d8047b9f-a8c7-4d74-b5c7-470510240b60</CS_ZLG_TRACK_ID>
<CS_SWIFTGPI_SVC_ID>001</CS_SWIFTGPI_SVC_ID>
</MeldungsRef>
<MeldungsRef>
<MSG_TX_ID_DECK>xxxxxxxxxx</MSG_TX_ID_DECK>
</MeldungsRef>
</Referenz>
<Mitteilung>
<MIT_BEGxxx</MIT_BEG>
<MIT_BEG_XML>
<Ustrd>xxx</Ustrd>
</MIT_BEG_XML>
<PURP_CD>SALA</PURP_CD>
</Mitteilung>
</Zahlung>
</Zahlungsliste>
</Auftrag>
The tag "Zahlung" can exist multiple times and that's OK, but into the the tag "Zahlung" is the
tag "MeldungsRef". This tag should exist zero or one time for every tag "Zahlung". That's a fault shown in the XML above. I now need a query to select all rows in the table, which contains an XML, where the tag "MeldungsRef" is multiple times there. How can I do that?
Thanks for helping me!
Regards,
mablaser
You're looking for a second appearance of the MeldungsRef node within a Zahlung node, so you can look directly for that. This query shows you the first and second instances of the node, using xmlquery() and specifying the appearance to find with [1] or [2]:
select id,
xmlquery(
'declare default element namespace "http://www.finnova.ch/ZV/EHF/021"; (: :)
/Body/Auftrag/Zahlungsliste/Zahlung/Referenz/MeldungsRef[1]'
passing xmltype(msg_body)
returning content
) as first,
xmlquery(
'declare default element namespace "http://www.finnova.ch/ZV/EHF/021"; (: :)
/Body/Auftrag/Zahlungsliste/Zahlung/Referenz/MeldungsRef[2]'
passing xmltype(msg_body)
returning content
) as second
from your_table;
You could look for the second being not-null, but it's easier to use the same XPath with xmlexists() to test whether a second child node exists:
select id
from your_table
where xmlexists(
'declare default element namespace "http://www.finnova.ch/ZV/EHF/021"; (: :)
/Body/Auftrag/Zahlungsliste/Zahlung/Referenz/MeldungsRef[2]'
passing xmltype(msg_body)
);
db<>fiddle with one good (single node) and one bad (multiple node) row.
i receive the following error: ORA-32512: type 'xquery external variable'
As your base column is a BLOB you need to tell it which character set it's it, e.g.:
passing xmltype(msg_body, nls_charset_id('UTF8'))
db<>fiddle.

Datawave extract string using regexp

I'm trying to extract a part of a string using a regular expression:
\[CODE\] \((.*?)\)
Given the string [CODE] (ABC-212) Rest of the title this match (https://regexr.com/557qd)
I used this regexp in my current java application, and now I'm trying to transform this on a Mule App.
Reading the documentation I see that I need to use a Transform, so I setup like this:
%dw 2.0
output application/json
---
vars.subject match(/\[CODE\] \((.*?)\)/)
I stored the string on the var called subject.
Using that regexp on Mule, do not works.. but in my java application does. What I'm doing wrong ?
DataWeave doesn't seem to have a global search flag (the g at the end of the original regex). This means the regular expression has to match the entire string. You use the parenthesis to indicate capture groups that will be returned additionally to the matched string.
Script:
vars.subject match(/^\[CODE\] \((.*)\).*/)
Output:
[
"[CODE] (ABC-212) Rest of the title",
"ABC-212"
]
Match in DataWeave returns an array that contains the entire matching expression, followed by all of the capture groups that match the provided regex. And in your case "Rest of the title" was not matching as per per Regex provided by you.
%dw 2.0
output application/json
var subject="[CODE] (ABC-212) Rest of the title"
---
//Catch here is, Regex should be fully matching as per input,
{
matchesOnly:subject matches /(\[CODE\]) \((.*?)\)[\w\W]*/,
matchOnly: subject match /(\[CODE\]) \((.*?)\)[\w\W]*/
}

Talend - Dynamic Column Name (Enterprise version)

Can anyone help me solve this case?
I have much file to process, two of them is like on below screenshot with my expected output.
I use this transformation on Talend: tFileList---tInputExcel---tUnpivotRow---tMap---tPostgresqlOutput
The output is different to my expected output. This is the screenshot of the output
Can anyone help me to reach my expected output which is like on my first picture above?
This will be pretty hard. You'd have to handle that as a text file. And whenever you found "store" value in the first column you'd update your type with the value.
Here's how I'd start:
Basically tJavaFlex begin piece would contain:
String col1Type
String colNType
main part:
if input_row.col0.equalsIgnoreCase("store") {
col1Type = input_row.col1;
col2Type = input_row.col2;
colNType = input_row.colN;
continue; /*(so this record will be Ignored for the rest of the components!)*/
}
output_row.col1Type = col1Type;
output_row.col1Value = Integer.valueOf(input_row.col1);
/*coz we have text and need numbers :( */
I think using propagate results will save you from writing down all the other fields.
And from here it would be very simple as you have key-type-value-type-value-type-value results.

form builder repeat index

I recently created a Form Builder form with a repeat to show a list of data. The repeat is working fine. My question is that i need to get the index for the data inside the repeat so that i can use it to get another set of data from tables.
Here is my
<fr:grid columns="2" repeat="true" ref="instance('fr-form-data')/name" id="data-repeat" origin="instance('fr-form-data-template')">
<xh:tr>
<xh:td>
<xf:output id="name-control" ref="person_name">
<xf:label>Name :</xf:label>
</xf:output>
</xh:td>
<xh:td>
<xf:trigger>
<xf:label>Get</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="instance('fr-param-instance')/person/mni" value="am_mni"/>
<xf:send submission="get-invl"/>
</xf:action>
</xf:trigger>
</xh:td>
</xh:tr>
</fr:grid>
I need to get the data to put inside here:
<xf:setvalue ref="instance('fr-param-instance')/person/mni" value="am_mni"/>
Thanks
If you have an element am_mni inside the repeat, at the same level of person_name, then your xf:setvalue can look like:
<xf:setvalue ref="instance('fr-param-instance')/person/mni"
value="context()/am_mni"/>
context() refers to the context in which the xf:setvalue runs, which will be the current repeat iteration, since it is inside a repeat. If you just write value="am_mni", this will be evaluated relative to the ref, and thus return instance('fr-param-instance')/person/mni/am_mni, which in your case is most likely an empty sequence.