XQuery to HTML table: generating columns - html-table

I'm working with a collection of 52 XML documents. I'm trying to write an XQuery to generate an HTML table from them. Each document would get one column with about 50 rows. The XQuery I have so far looks like this:
declare variable $bills := collection('BillsXML/?select=*.xml');
declare variable $week :=$bills/bill/data(#week);
<html>
<head></head>
<body>
<table>
<tr><th>Cause</th><th>Number</th></tr>
{
for $b in $bills
let $causes := $b//item/data(#cause)
for $c in $causes
let $deaths-per-cause := $b//item[data(#cause)=$c]/data(#number)
return <tr><td>{$c}</td><td>{$deaths-per-cause}</td></tr>
}
</table>
</body>
</html>
This works fine when run over one $b (document): I get a two-column table, with the fifty causes of death making fifty rows using the $c for-loop. But what I want to do is also to automatically generate the fifty-two columns, one per $b (document). The first column should still list the causes of death, and each column after should have the document's $week number in the and the $deaths-per-cause from that document arrayed down the cells of the column. Is this possible? For example, do I write two FLWOR statements, one to generate the columns and the other to generate the rows to populate them? And if so, how do they interlock?

You haven't shown your XML source so this is a rough guess, but you want something like
for $c in $causes return
<tr>{
<td>{$c}</td>,
for $b in $bills return
<td>{$b//item[#cause=$c]/data(#number)}</td>
}</tr>

Related

Coldfusion - Need to get string data between opening and closing tags

I am trying to get specific data between two strings which are a opening and closing tag. Normally I would just parse it using XmlParse but the problem is it has a lot of other junk in the dataset.
Here is an example of the large string:
test of data need to parse:<?xml version="1.0" encoding="UTF-8"?><alert xmlns="urn:oasis:names:tc::cap:1.2"><identifier>_2020-12-16T17:32:5620201116173256</identifier><sender>683</sender><sent>2020-12-16T17:32:56-05:00</sent><status>Test</status><msgType>Alert</msgType><source>test of data need to parse</source><scope>Public</scope><addresses/><code>Test1.0</code><note>WENS IPAWS</note><info><language>en-US</language></info>
<capsig:Signature xmlns:capsig="http://www.w3.org/2000/09/xmldsig">
<capsig:Info>
<capsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n"/>
<capsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-morersa-sha256"/>
<capsig:Referrer URI="">
<capsig:Trans>
<capsig:Trans Algorithm="http://www.w3.org/2000/09/xmldsigenveloped-signature"/>
</capsig:Trans>
<capsig:DMethod Algorithm="http://www.w3.org/2001/04/xmlencsha256"/>
<capsig:DigestValue>wjL4tqltJY7m/4=</capsig:DigestValue>
</capsig:Referrer>
</capsig:Info>
test of data need to parse:<?xml version="1.0" encoding="UTF-8"?><alert xmlns="urn:oasis:names:tc::cap:1.2"><identifier>_2020-12-16T17:32:5620201116173256</identifier><sender>683</sender><sent>2020-12-16T17:32:56-05:00</sent><status>Test</status><msgType>Alert</msgType><source>test of data need to parse</source><scope>Public</scope><addresses/><code>Test1.0</code><note>WENS IPAWS</note><info><language>en-US</language></info>
So what I need to do is just extract the following:
<capsig:Info>
<capsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n"/>
<capsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-morersa-sha256"/>
<capsig:Referrer URL="">
<capsig:Trans>
<capsig:Trans Algorithm="http://www.w3.org/2000/09/xmldsigenveloped-signature"/>
</capsig:Trans>
<capsig:DMethod Algorithm="http://www.w3.org/2001/04/xmlencsha256"/>
<capsig:DigestValue>wjL4tqltJY7m/4=</capsig:DigestValue>
</capsig:Referrer>
</capsig:Info>
I have searched everywhere and I have found where things can be done with characters and counts but none of them really worked. Tried doing it with SQL but because the constant change in the string it causes issues. So my plan was get everything after "capsig:Info" and before "</capsig:Info>" then insert it into a table.
Is there a way to do this with Coldfusion?
Any suggestions would be appreciated.
Thanks!
Yes, you can use a regular expression match to extract the substring containing the text between the <capsig:Info> ... </capsig:Info> tags by using the ColdFusion function reMatch() which will return an array of all substrings that match the specified pattern. This can be done using the line of code below.
<!--- Use reMatch to extract all pattern matches into an array --->
<cfset parsedXml = reMatch("<capsig:Info>(.*?)</capsig:Info>", xmlToParse)>
<!--- parsedXml is an array of strings. The result will be found in the first array element as such --->
<cfdump var="#parsedXml[1]#" label="parsedXml">
You can see this using the demo here.
https://trycf.com/gist/00be732d93ef49b2427768e18e371527/lucee5?theme=monokai

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.

How to insert value to muliple column from textarea use PHP?

I want to insert value to multiple database from Textarea, example i enter value to textarea and submit :
1|Vo Huu Nhan 1
2|Vo huu Nhan 2
3|Vo Huu Nhan 3
After submit i want insert value before "|" to column tap and value after "|" to column player
My code :
<form action="Post.php" method="POST">
<textarea name="tapphim"></textarea>
<input type="submit" value="submit"/></form>
Please help me create Post.php file right way
Firstly which programming language are you using?
For all programming languages, the concept is similar.
Take the input text from the textarea , then explode the '|' out of it ....then it becomes an array .
After that insert the first value of the array into the tap column then the other one into the players column.
The expression might look like this:
array[0] into tap column,
array[1] into players column
But i will like to know the programming language you want to use in achieving this
I hope it enlightens you.
Since you are using php
`if(isset($_POST['tapphim']) && !empty($_POST['tapphim'])
{
$textAreaInput = explode("|", $_POST['tapphim']);
$tapValue = $textAreaInput[0];
$playerName = $textAreaInput[1];
$sql = mysqli_query($con,"insert into
playersTble(tap,players)
values('$textAreaInput','$playerName");
if($sql){
echo "data saved!";
}
}`
i Hope this solves your problem.
Make sure you read about sanitizing input in PHP
Try this,
if(isset($_POST['tapphim'])){
$lineSplit=explode("\n", $_POST['tapphim']);
foreach ($lineSplit as $line) {
$splitArr=explode("|", $line);
$fieldOne=$splitArr[0];
$fieldTwo=$splitArr[1];
// insert to db
}
}
You may want to use htmlspecialchars($_POST['tapphim']) or mysql_real_escape_string($_POST['tapphim']) to clear post variables from dangerous characters for security reasons especially if you don't use PDO connection to connect your database.

Is there any way to convert string patterns as shown in the map below?

Trying to convert 'Currently' patterns in the above table to 'Turn It Into' patterns in the data set ...
Examples are shown in the next 2 columns for each one....
I tried different ways but I could not get required output ....
Here is the code to get the input data....
data Current;
Input Currently :$40.;
Datalines;
HiKumar"^TM1()^",test
HiKumar"^TM2()^"
HiKumar^TM3()^HiKumar
HiKumar^f(‘VARNAME’).any(‘#’)^
HiKumar^f(‘VARNAME’)^
HiKumar^f(‘VARNAME’).get()==’#’^
HiKumar^f(‘VARNAME’)==’#’^
HiKumar^f(‘VARNAME’).toNumber()^
HiKumar^f(‘VARNAME’).toString()^
HiKumar^f(‘VARNAME’).toString().toLowerCase()^
HiKumar^f(‘VARNAME’).toString().toUpperCase()^
HiKumar^f(‘IFCONDITION’)?’THENTEXT’:’ELSETEXT’^
HiKumar<br>
HiKumar<br/>
HiKumar<br />
HiKumar^MobileHeader()^
HiKumar^MobileFooter()^
HiKumar<u>
HiKumar</u>
HiKumar&nbsp
;
run;
I'd go with regular expressions. You'll need several; here's one to start. (The quotation characters will probably be mucked up by the web browser and/or SAS, so I would recommend replacing those manually rather than trusting the copy/paste if they don't work at first). This only identifies the fourth row, but similar regex's can be constructed for the other rows (and some you should be able to use for multiple rows).
data want;
set current;
rx_1 = prxparse("/\^f\(‘(\w*?)’\)\^/");
rc_1 = prxmatch(rx_1,currently);
if rc_1 ne 0 then have = prxposn(rx_1,1,currently);
run;

Export SQL query results to XML format using powershell

I need to make an XML file based on the SQL query that I run using powershell. I already know the schema for the XML that I need to create. The query results need to be looped through and I want to add each data value to specific XML node as per the schema.
I am able to run the query and get the results I need but I am having issues placing the data as per prescribed format.
Here's an example of how I am trying to accomplish this:
**Parsing the XMl Template
$XmlTemplate= [xml](get-content $xml) ($xml is the schema I have from the client)
***Parsing through XML Template and jumping to tag
$PlanIDXML= $XmlTemplate.NpiLink.PlanProvider.PlanID (to get to the node I need to enter data into)
**Parsing through XML Template and jumping to tag
$PlannameXML= $XmlTemplate.NpiLink.PlanProvider.PlanName (to get to the node I need to enter data into)
sample qry;
select PlanID,PlanName from plan
**Assuming I ran my query and saved the results as $qryresults***
foreach($result in $qryresults)
{
$PlanID=$result.PlanID
$PlanName=$result.PlanName
**Make Clone
$NewPlanIDXML=$PlanIDXML.Clone()
**Make Changes to the data
$NewPlanIDXML=$PlanID
***Append
$PlanIDXML.AppendChild($NewPlanIDXML)
* Do the same thing for Plan Name **
$PlanNameXML=$result.PlanName
}
$XmlTemplate.Save('filepath')
My concern is that I need to do this for each plan or planid that I get in my query results and I need to keep generating tags and tags even and append them to orginal nodes and save the schema.
So, if my query results have 10 Plan IDs it should continue to generate new Plan ID tags and Plan Name tags.
Its not letting me append (because system.string can not be converted to system.xml). I am really stuck and if you have a better approach on how to handle this, I am all ears.
Thanks much in advance!!!
You might be overengineering this a bit. If you have a template for the XML node, just treat it as a string, popping your values in at the appropriate place. Generate some array of these nodes as strings, then join them together and save to disk.
Let's say your template looks like this (type in some tokens yourself where generated values should go):
--Template.xml---
<Node attr="##VALUE1##">
<Param>##VALUE2##</Param>
</Node>
And you want to run some query to generate a bunch of these nodes, filling in VALUE1 and VALUE2. Then something like this could work:
$template = (gc .\Template.xml) -join "`r`n"
$val1Token = '##VALUE1##'
$val2Token = '##VALUE2##'
$nodes = foreach( $item in Run-Query)
{
# simple string replace
$result = $template
$result = $result.Replace($val1Token, $item.Value1)
$result = $result.Replace($val2Token, $item.Value2)
$result
}
# you have all nodes in a string array, just join them together along with parent node
$newXml = (#("<Nodes>") + $nodes + "</Nodes>") -join "`r`n"
$newXml | out-file .\Results.xml