How to pass 'as' argument to gdbus? - dbus

This is a part of xml.
<method name="Mount">
<annotation name="org.chromium.DBus.Method.Kind" value="simple" />
<arg name="path" type="s" direction="in" />
<arg name="filesystem_type" type="s" direction="in" />
<arg name="options" type="as" direction="in" />
And this is what I want to implement exactly. (captured method call by dbus-monitor)
method call time=1675906347.661521 sender=:1.31 -> destination=org.chromium.CrosDisks serial=4557 path=/org/chromium/CrosDisks; interface=org.chromium.CrosDisks; member=Mount
string "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0/host1/target1:0:0/1:0:0:0/block/sdb/sdb1"
string ""
array [
string "rw"
string "mountlabel=MY-STORAGE"
]
And This is what I tried by gdbus.
gdbus call --system --dest org.chromium.CrosDisks --object-path /org/chromium/CrosDisks --method org.chromium.CrosDisks.Mount "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0/host1/target1:0:0/1:0:0:0/block/sdb/sdb1" “” [“rw” "mountlabel=MY-STORAGE"]
The I got errors.
(gdbus call:12863): GLib-CRITICAL **: 23:37:56.454: g_variant_new_string: assertion 'g_utf8_validate (string, -1, NULL)' failed
[Invalid UTF-8] Error parsing parameter 2: expected value:
\xe2\x80
^
(gdbus call:12863): GLib-CRITICAL **: 23:37:56.455: g_error_free: assertion 'error != NULL' failed
I think my expression for the type="as" is wrong.
Can someone help me?

I found the answer.
"['rw', 'mountlabel=MY-STORAGE']"

Related

How to use XQuery to simulate STRING_AGG() (grouped string concatenation)?

I have XML data which I need to convert to relational form. I use XQuery cause I don't know the number of address nodes. I'd like to get the whole address/adresses separeted by a comma. I guess I need to use LET clause but I'm still receiving an error.
Here's my code:
declare #xml as xml = '<root>
<Row>
<proceeding>
<signatures>V GU 86/18</signatures>
<signatures>V GUp 9/19</signatures>
<signatures>V GUp 8/19</signatures>
</proceeding>
<entity>
<info>
<cleaned_name>Kate Smith</cleaned_name>
</info>
<address>
<town>London </town>
<house_number>1 </house_number>
<flat_number>1</flat_number>
<street>Downing Street</street>
<zip_code>00-001</zip_code>
</address>
</entity>
<entity>
<info>
<cleaned_name>John Smith</cleaned_name>
</info>
<address>
<town>Washington </town>
<house_number>1</house_number>
<flat_number>1</flat_number>
<street>Pennsylvania Avenue</street>
<zip_code>00-001</zip_code>
</address>
</entity>
</Row>
</root>'
select
isnull(STUFF(a.x.query('for $s in entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
--,isnull(STUFF(a.x.query('for $s in entity let $L := $s/entity/address return <x>{concat(",",Address="{$s/Address}")}</x>').value('.','varchar(max)'),1,1,''),'')
from #xml.nodes('/root/Row') as a(x)
My desired outcome
Are you looking for this?
select
isnull(STUFF(a.x.query('for $s in entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
,isnull(STUFF(a.x.query('for $s in entity
return <x>
{
concat(", ",($s/address/zip_code/text())[1]," "
,($s/address/town/text())[1]," "
,($s/address/street/text())[1]," "
,($s/address/house_number/text())[1],"/"
,($s/address/flat_number/text())[1]
)
}
</x>').value('.','varchar(max)'),1,2,''),'')
from #xml.nodes('/root/Row') as a(x);
The result
Nazwa podmiotu Sygnatura AllAdresses
Kate Smith,John Smith V GU 86/18,V GUp 9/19,V GUp 8/19 00-001 London Downing Street 1 /1, 00-001 Washington Pennsylvania Avenue 1/1
UPDATE Multiple addresses and identical data
You can try this (according to your comment)
Your test data with one second address and one copied address:
declare #xml as xml = '<root>
<Row>
<proceeding>
<signatures>V GU 86/18</signatures>
<signatures>V GUp 9/19</signatures>
<signatures>V GUp 8/19</signatures>
</proceeding>
<entity>
<info>
<cleaned_name>Kate Smith</cleaned_name>
</info>
<address>
<town>London </town>
<house_number>1 </house_number>
<flat_number>1</flat_number>
<street>Downing Street</street>
<zip_code>00-001</zip_code>
</address>
<address>
<town>Yorkshire </town>
<house_number>1 </house_number>
<flat_number>1</flat_number>
<street>Morning Street</street>
<zip_code>00-999</zip_code>
</address>
</entity>
<entity>
<info>
<cleaned_name>John Smith</cleaned_name>
</info>
<address>
<town>Washington </town>
<house_number>1</house_number>
<flat_number>1</flat_number>
<street>Pennsylvania Avenue</street>
<zip_code>00-001</zip_code>
</address>
<address>
<town>Washington </town>
<house_number>1</house_number>
<flat_number>1</flat_number>
<street>Pennsylvania Avenue</street>
<zip_code>00-001</zip_code>
</address>
</entity>
</Row>
</root>'
--The query
select
isnull(STUFF(a.x.query('for $s in entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
,isnull(STUFF(a.x.query('for $s in entity/address
return
<x>{concat(", ",($s/zip_code/text())[1]," "
,($s/town/text())[1]," "
,($s/street/text())[1]," "
,($s/house_number/text())[1],"/"
,($s/flat_number/text())[1]
)}</x>')
.query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'')
from #xml.nodes('/root/Row') as a(x);
The idea in short:
We use the first XQuery to create a simple XML fragment like this
<x>, 00-001 London Downing Street 1 /1</x>
<x>, 00-999 Yorkshire Morning Street 1 /1</x>
<x>, 00-001 Washington Pennsylvania Avenue 1/1</x>
<x>, 00-001 Washington Pennsylvania Avenue 1/1</x>
With this we can use a second XQuery and place distinct-values() there.

bash to parse XML into multidimensional array

I have a XML file which I want to parse into bash variables/arrays.
I have limited linux commands (busybox) available since I am working on a NAS box.
My XML file looks like this:
<?xml version="1.0" encoding="UTF-8"?> .
<WEBCAMS>
<CAM>
<DESCRIPTION>description for cam 1</DESCRIPTION>
<URL>http://myURLtoWebcam1/cam1/pic.jpg</URL>
<FILENAME>filename1</FILENAME>
</CAM>
<CAM>
<DESCRIPTION>description for cam 2</DESCRIPTION>
<URL>http://myURLtoWebcam2/cam2/pic.jpg</URL>
<FILENAME>filename2</FILENAME>
</CAM>
</WEBCAMS>
my bash script so far:
#!/bin/sh
rdom () { local IFS=\> ; read -d \< E C ;}
while rdom; do
if [[ $E = DESCRIPTION ]]; then
counter=$((counter+1))
declare cam$counter="$C"
fi
done < webcams.xml
I want to get the XML content like the following:
echo "Cam1 description: ${cam1[0]}"; ## should show: description for cam 1
echo "Cam1 URL: ${cam1[1]}"; ## should show: http://myURLtoWebcam1/cam1/pic.jpg
echo "Cam1 filename: ${cam1[2]}"; should show: filename1
echo "Cam2 description: ${cam2[0]}"; ## should show: description for cam 2
echo "Cam2 URL: ${cam2[1]}"; ## should show: http://myURLtoWebcam1/cam2/pic.jpg
echo "Cam2 filename: ${cam2[2]}"; ## should show: filename2
So far I am only able to read the "DESCRIPTION" fields into bash variables.
Any idea how to get the other fields "URL" and "FILENAME" into my arrays/variables? The so far found solutions did not fit or could not be modified to my needs due to the limited Linux commands on my NAS.
If XSLTPROC is available you can use it - bonus its a real XML parser.
> xsltproc transform.xsl webcams.xml
Cam1 description: description for cam 1
Cam1 URL: http://myURLtoWebcam1/cam1/pic.jpg
Cam1 filename: filename1
Cam2 description: description for cam 2
Cam2 URL: http://myURLtoWebcam2/cam2/pic.jpg
Cam2 filename: filename2
Where transform.xsl is
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="CAM">
<xsl:variable name="i" select="position()" />
Cam<xsl:value-of select="$i"/> description: <xsl:value-of select="DESCRIPTION"/>
Cam<xsl:value-of select="$i"/> URL: <xsl:value-of select="URL"/>
Cam<xsl:value-of select="$i"/> filename: <xsl:value-of select="FILENAME"/>
</xsl:template>
<xsl:template match="/WEBCAMS"><xsl:apply-templates select="*"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
This seems to work ... but still the 1,5D dimensional array or the way to escape variables makes me headache - see below problems within a FOR loop:
#!/bin/sh
rdom () { local IFS=\> ; read -d \< E C ;}
while rdom; do
if [[ $E = DESCRIPTION ]]; then
counter0=$((counter0+1))
declare -a cam$((counter0))[0]="$C"
fi
if [[ $E = URL ]]; then
counter1=$((counter1+1))
declare -a cam$((counter1))[1]="$C"
fi
if [[ $E = FILENAME ]]; then
counter2=$((counter2+1))
declare -a cam$((counter2))[2]="$C"
fi
done < webcams.xml
echo "Cam1 description: ${cam1[0]}";
echo "Cam1 URL: ${cam1[1]}";
echo "Cam1 filename: ${cam1[2]}";
echo "Cam2 description: ${cam2[0]}";
echo "Cam2 URL: ${cam2[1]}";
echo "Cam2 filename: ${cam2[2]}";
But it is still impossible to get the values within a FOR loop like:
for (( c=1; c<=$counter0; c++ ))
do
var=cam$c;
echo "Cam$c description: ${!var[0]}";
echo "Cam$c URL: ${!var[1]}";
echo "Cam$c filename: ${!var[2]}";
done

Parsing with MPC library returns error on grammar definition

I'm trying to use MPC to define a grammar for a language called Wittgen (https://esolangs.org/wiki/Wittgen)
I defined the following grammar:
mpc_parser_t* Variable = mpc_new("variable");
mpc_parser_t* Assign_Operator = mpc_new("assign");
mpc_parser_t* Remind_Operator = mpc_new("remind");
mpc_parser_t* Expr = mpc_new("expr");
mpc_parser_t* Envinronment = mpc_new("envinronment");
mpca_lang(MPCA_LANG_DEFAULT,
" variable : /[a-zA-Z0-9]+/ ;"
" assign : '=' ;"
" remind : '#' ;"
" expr : <variable> | <remind> <variable> '}' | <variable> <assign> <expr>+ '}' ;"
" envinronment : /^/<expr>+/$/ ;",
Variable, Assign_Operator, Remind_Operator, Expr, Envinronment);
when I try to input a variable or a remind operator (like "foo247" or "#foo247}") it parses it correctly,
but when I try to parse an assignment ("foo247=foo}"), it returns me just
WITTGEN> foo357=foo}
<stdin>:1:7: error: expected one of 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ', one or more of one of 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ', '#' or end of input at '='
I can't find the error, I'm sure something is wrong defined in the grammar, but I can't find any clue in the official documentation or in the examples
I'm not an expert on mpc and I may be wrong, in fact I'm having my own problems with it at the moment, but I don't think it supports left recursion. So since expr is contained within the expr rule it causes an error.
Edit* I was able to solve my issue by moving part of my expansion over. So the equivalent for yours would be to move variable all the way to the right so it tries to parse using the other two expansions first. I can't say for sure if that's causing your issue, but it could be worth a shot.
I had my question answered from the author of mpc here:
I simply changed the part of rule definition from
" expr : <variable> | <remind> <variable> '}' | <variable> <assign> <expr>+ '}' ;"
to:
" expr : <remind> <variable> '}' | <variable> <assign> <expr>+ '}' | <variable>;"
it was happening because there's no backtracking in mpc, so the evaluation rule order is important

Get xmllint xpath nodes to arrays

I have NMAP-output xml-file like this:
<host><status state="down" reason="no-response" reason_ttl="0"/>
<address addr="192.168.1.1" addrtype="ipv4"/>
</host>
<taskbegin task="SYN Stealth Scan" time="1457545799"/>
<taskend task="SYN Stealth Scan" time="1457545841" extrainfo="1600 total ports"/>
<host starttime="1457545794" endtime="1457545839"><status state="up" reason="echo-reply" reason_ttl="243"/>
<address addr="192.168.1.2" addrtype="ipv4"/>
<hostnames>
<hostname name="192-168-1-2.liibalaaba.com" type="PTR"/>
</hostnames>
<ports><extraports state="closed" count="100">
<extrareasons reason="resets" count="100"/>
</extraports>
</ports>
<times srtt="6454" rttvar="163" to="100000"/>
</host>
<host starttime="1457545794" endtime="1457545837"><status state="up" reason="echo-reply" reason_ttl="51"/>
<address addr="192.168.1.3" addrtype="ipv4"/>
<hostnames>
<hostname name="192-168-1-3.liibalaaba.com" type="PTR"/>
</hostnames>
<ports><extraports state="filtered" count="98">
<extrareasons reason="no-responses" count="98"/>
</extraports>
<port protocol="tcp" portid="80"></port>
<port protocol="tcp" portid="443"></port>
</ports>
<times srtt="6378" rttvar="191" to="100000"/>
</host>
<host starttime="1457545794" endtime="1457545841"><status state="up" reason="echo-reply" reason_ttl="115"/>
<address addr="192.168.1.4" addrtype="ipv4"/>
<hostnames>
<hostname name="192-168-1-4.liibalaaba.com" type="PTR"/>
</hostnames>
<ports><extraports state="filtered" count="97">
<extrareasons reason="no-responses" count="97"/>
</extraports>
<port protocol="tcp" portid="80"></port>
<port protocol="tcp" portid="81"></port>
<port protocol="tcp" portid="443"></port>
</ports>
<times srtt="6417" rttvar="113" to="100000"/>
</host>
How I can put only the hosts that have open ports to an array and then to readable format? (Do I even need an array?)
Something like this:
address:192.168.1.3 [0,0]
open ports:80 [0,1], 443 [0,2]
address:192.168.1.4 [1,0]
open ports:80[1,1], 81 [1,2], 443 [1,3]
Now i'm using xmllint xpath combo, but it just splits out every address that has open ports to same line:
`xmllint --xpath "//*[local-name()='host']/*[local-name()='address']/#addr | //*[local-name()='ports']/*[local-name()='port']/#portid" nmap-scan.xml > result.txt`
Thanks for help!

How i set variable in XSL in for

Sry, when i don't i find answare, but i don't make correct question. I have APEX 4 and trying create report from multiarray select. For example data is:
Name1 Value1
Name1 Value2
Name1 Value3
Name1 Value4
Name2 Value5
Name2 Value6
Name2 Value7
and I need output in report:
-Name1
--Value1
--Value2
--Value3
--Value4
-Name2
--Value5
--Value6
--Value7
I need do it in XSL similiar as php:
$x_key= '';
foreach($arr as $key=>$value)
{
if ($x_key != $key) {
$x_key = $key;
echo "-$key\n";
}
echo "--$value\n";
}
My code possible is (but don't do it what I want):
<xsl:variable name="NAMEOLD" select="X" />
<xsl:for-each select="//ROWSET1_ROW[position()]">
<xsl:variable name="NAME" select="NAME_NUMBER" />
<xsl:choose>
<xsl:when test="NAME!=NAMEOLD">
<xsl:variable name="NAMEOLD" select="NAME" />
<fo:table-row>
<fo:table-cell xsl:use-attribute-sets="cell-transparent" >
<fo:block xsl:use-attribute-sets="align-left txt" keep-together.within-page="always">
<xsl:value-of select="NAME_NUMBER"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:when>
</xsl:choose>
<fo:table-row>
<fo:table-cell xsl:use-attribute-sets="cell-transparent" >
<fo:block xsl:use-attribute-sets="align-left txt" keep-together.within-page="always">
<xsl:value-of select="VALUE"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
Thanks for any clue or answer
Stoupa101
You haven't shown your input XML. The simplest solution is along the following lines (note this requires XSLT 2.0):
<xsl:for-each-group select="ROW" group-adjacent="name">
<h1><xsl:value-of select="current-grouping-key"></h1>
<xsl:for-each select="current-group()"/>
<p><xsl:value-of select="value"/></p>
</xsl:for-each-group>
Don't try to do it the PHP way - there's no point writing low-level code when you have a high-level language.

Resources