How to mapping prefixes to nodes in Jena SDB - jena

After numerous attempts, I entered triple and prefixes data into SDB through add (Resource, Property, String) and setNsPrefix (ns, prefix). However, only hash, lex, and type for triple are stored in nods.
Is it possible to mapping the information of prefixes to the hash, lex, and type of nodes?
`
model.setNsPrefix(ns, prefix);
model.setNsPrefix(ns2, prefix2);
model.setNsPrefix(ns3, prefix3);
model.setNsPrefix(ns3, prefix3);
for(i = 0; i<index; i++) {
Resource s_A = model.createResource(A[i].s);
Property p_A = model.createProperty(A[i].p);
Resource s_B = model.createResource(B[i].s);
Property p_B = model.createProperty(B[i].p);
Resource s_C = model.createResource(C[i].s);
Property p_C = model.createProperty(C[i].p);
Resource s_D = model.createResource(D[i].s);
Property p_D = model.createProperty(D[i].p);
Resource s_E = model.createResource(E[i].s);
Property p_E = model.createProperty(E[i].p);
model.add(s_A, p_A, A[i].o);
model.add(s_B, p_B, B[i].o);
model.add(s_C, p_C, C[i].o);
model.add(s_D, p_D, D[i].o);
model.add(s_E, p_E, E[i].o);
}
`

Prefix are stored in a separate table.
As a general point, prefixes have no part in the RDF data model. They only exist to assist formatting output. there is no mapping from prefix to terms using the URI of the prefix name. That is all sorted out on parsing input.
Use on output is determined by the RDF writer outputting RDF; nothing to do with SDB which just stores the prefixes.
See class PrefixMappingSDB.

Related

Print formatted string using a std::vector (of variable size)

I use the Magento 2 REST API and want to handle errors that get thrown in C++.
Example error response:
{
"message": "Could not save category: %1",
"parameters": [
"URL key for specified store already exists."
]
}
I can retrieve both of these into a String and std::vector which leaves me with the question:
How am I able to return a String that is formatted by filling the placeholders?
With a fixed size, I could do something along the lines of this
char* buffer = new char[200];
String message = "Could not save category: %1";
std::vector<String> parameters = {"URL key for specified store already exists."};
String result = sprintf(buffer,message.c_str(),parameters[0]);
But, alas, I do not know the size beforehand.
How should I go about doing this? Are there stl functions that could help, should I be using self-written templates(no experience with this), can I convert the std::vector to a va_list, or are there other solutions?
Edit: I didn't notice this asks for a C++ dialect and not Standard C++. Leaving it for now, might be of use for other people.
Nothing standard exists that will do that automatically. That being said, if your interpolation format is just %<number> it might be easy enough to write:
string message = "Could not save category: %1";
std::vector<string> parameters = {"URL key for specified store already exists."};
for (size_t i = 0; i < parameters.size(); ++i) {
const auto interp = "%" + std::to_string(i+1);
const size_t pos = message.find(interp);
if (pos != std::string::npos)
message.replace(pos, interp.size(), parameters[i]);
}
This will put the result in the message string. Of course this implementation is rather limited and not particularly efficient, but again, doing this properly requires a library-sized solution, not SO-answer-sized one.
live version.

InfluxDB templating query - referring to measuerments?

I'm trying to make templates for my dahboards, and I have problems when it comes to referring to measuerment names.
My variables:
$space = SHOW MEASUREMENTS
Then I would like a variable that contains only values from a specific $space, which is actually a MEASUREMENT:
$app = SHOW TAG VALUES WITH KEY = "Application" WHERE MEASUREMENT =~ /^$space$/
Here I get a message: Template variables could not be initialized: error parsing query: found MEASUREMENT, expected identifier, string, number, bool at line 1, char 48
In the official example it is like this, though it refers to another tag:
$datacenter = SHOW TAG VALUES WITH KEY = "datacenter"
$host = SHOW TAG VALUES WITH KEY = "hostname" WHERE "datacenter" =~ /^$datacenter$/
I cannot find any info how to refer to MEASUREMENTS which would work. WHERE, WITH, etc.. Maybe is it not possible at all?
I found only this in the official tutorial, but this is for keys, not values.
SHOW TAG KEYS [FROM <measurement_name>]
I actually figured it out:
SHOW TAG VALUES FROM /^$space$/ WITH KEY = "Application"

Can I write headers with the CsvProvider without providing a sample?

Why is it that if I create a new CSV type with the CsvProvider<> in F# like this:
type ThisCsv = CsvProvider<Schema = "A (decimal), B (string), C (decimal)", HasHeaders = false>
then create/fill/save the .csv, the resulting file does not contain the headers in the schema I specified? It seems like there should be a way to include headers in the final .csv file, but that's not the case.
Setting HasHeaders = true errors out, because there's no sample provided. The only way for HasHeaders = true to work is to have a sample .csv. It seems to me that there should be a way to specify the schema without a sample and also include the headers in the final file.
Am I missing something when I use [nameOfMyCSV].Save() that can include the headers from the schema or can this not be done?
I'm afraid the headers from the Schema are only used for the property names of the row. To have them in the file you save you have to provide Sample. Though, the sample can contain only the headers. Also, HasHeaders has to be set to true:
type ThisCsv = CsvProvider<
Sample="A, B, C",
Schema = "A(decimal), B, C(decimal)",
HasHeaders = true>
If the sample contains only headers then if you want to specify data types the schema has to be provided as well.
You can see that the schema is used for property only when you rename the Sample headers in the Schema:
type ThisCsv = CsvProvider<
Sample="A, B, C",
Schema = "A->AA(decimal), B->BB, C(decimal)",
HasHeaders = true>
Then the generated row will have properties like AA, B, CC. But the file generated will still have A, B, C. Also, the Headers property of a csv you created using this schema will be Some [|"A"; "B"; "C"|]:
// Run in F# Interactive
let myCsv = new ThisCsv([ThisCsv.Row(1.0m, "a", 2.0m)])
myCsv.Headers
// The last line returns: Some [|"A"; "B"; "C"|]
Also, to get better understanding of what's happening inside the parser worth taking a look at the source code in GitHub: CSV folder in general and CsvRuntime.fs in particular.

How to remove non-ascii char from MQ messages with ESQL

CONCLUSION:
For some reason the flow wouldn't let me convert the incoming message to a BLOB by changing the Message Domain property of the Input Node so I added a Reset Content Descriptor node before the Compute Node with the code from the accepted answer. On the line that parses the XML and creates the XMLNSC Child for the message I was getting a 'CHARACTER:Invalid wire format received' error so I took that line out and added another Reset Content Descriptor node after the Compute Node instead. Now it parses and replaces the Unicode characters with spaces. So now it doesn't crash.
Here is the code for the added Compute Node:
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
DECLARE NonPrintable BLOB X'0001020304050607080B0C0E0F101112131415161718191A1B1C1D1E1F7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF1F2F3F4F5F6F7F8F9FAFBFCFDFEFF';
DECLARE Printable BLOB X'20202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020';
DECLARE Fixed BLOB TRANSLATE(InputRoot.BLOB.BLOB, NonPrintable, Printable);
SET OutputRoot = InputRoot;
SET OutputRoot.BLOB.BLOB = Fixed;
RETURN TRUE;
END;
UPDATE:
The message is being parsed as XML using XMLNSC. Thought that would cause a problem, but it does not appear to be.
Now I'm using PHP. I've created a node to plug into the legacy flow. Here's the relevant code:
class fixIncompetence {
function evaluate ($output_assembly,$input_assembly) {
$output_assembly->MRM = $input_assembly->MRM;
$output_assembly->MQMD = $input_assembly->MQMD;
$tmp = htmlentities($input_assembly->MRM->VALUE_TO_FIX, ENT_HTML5|ENT_SUBSTITUTE,'UTF-8');
if (!empty($tmp)) {
$output_assembly->MRM->VALUE_TO_FIX = $tmp;
}
// Ensure there are no null MRM fields. MessageBroker is strict.
foreach ($output_assembly->MRM as $key => $val) {
if (empty($val)) {
$output_assembly->MRM->$key = '';
}
}
}
}
Right now I'm getting a vague error about read only messages, but before that it wasn't working either.
Original Question:
For some reason I am unable to impress upon the senders of our MQ
messages that smart quotes, endashes, emdashes, and such crash our XML
parser.
I managed to make a working solution with SQL queries, but it wasted
too many resources. Here's the last thing I tried, but it didn't work
either:
CREATE FUNCTION CLEAN(IN STR CHAR) RETURNS CHAR BEGIN
SET STR = REPLACE('–',STR,'–');
SET STR = REPLACE('—',STR,'—');
SET STR = REPLACE('·',STR,'·');
SET STR = REPLACE('“',STR,'“');
SET STR = REPLACE('”',STR,'”');
SET STR = REPLACE('‘',STR,'&lsqo;');
SET STR = REPLACE('’',STR,'’');
SET STR = REPLACE('•',STR,'•');
SET STR = REPLACE('°',STR,'°');
RETURN STR;
END;
As you can see I'm not very good at this. I have tried reading about
various ESQL string functions without much success.
So in ESQL you can use the TRANSLATE function.
The following is a snippet I use to clean up a BLOB containing non-ASCII low hex values so that it then be cast into a usable character string.
You should be able to modify it to change your undesired characters into something more benign. Basically each hex value in NonPrintable gets translated into its positional equivalent in Printable, in this case always a full-stop i.e. x'2E' in ASCII. You'll need to make your BLOB's long enough to cover the desired range of hex values.
DECLARE NonPrintable BLOB X'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F';
DECLARE Printable BLOB X'2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E';
SET WorkBlob = TRANSLATE(WorkBlob, NonPrintable, Printable);
BTW if messages with invalid characters only come in every now and then I'd probably specify BLOB on the input node and then use something similar to the following to invoke the XMLNSC parser.
CREATE LASTCHILD OF OutputRoot DOMAIN 'XMLNSC'
PARSE(InputRoot.BLOB.BLOB CCSID InputRoot.Properties.CodedCharSetId ENCODING InputRoot.Properties.Encoding);
With the exception terminal wired up you can then correct the BLOB's of any messages containing parser breaking invalid characters before attempting to reparse.
Finally my best wishes as I've had a number of battles over the years with being forced to correct invalid message content in the "Integration Layer" after all that's what it's meant to do.

Omniture custom link tracking - how to track multiple events

Which property is the right one to pass tracking events when using omniture custom link tracking?
Actually i'm having this three properties:
s.linkTrackVars = 'events,prop55';
s.events = ['event12','some other event'];
s.linkTrackEvents = 'event12';
but i'm not shure if that this is correct way. Should the s.events also be passed to the s.linkTrackEvents like:
s.linkTrackEvents = s.events;
I'm implementing omniture for a customer so i haven't access to the omniture analytics tool.
Any suggestions
linkTrackVars should be a string value and expects a comma delimited list (no spaces) of each variable you want to track, no object namespace prefix. This includes events variable if you are tracking events.
linkTrackEvents should be a string value and expects a comma delimited list (no spaces) of each event you want to track. This should only be the base event itself, not serialization or custom numeric values that you may pop in events. For example, if you have s.events='event1:12345,event2=23'; you should only have s.linkTrackEvents='event1,event2';
events should be a string value and expects a comma delimited list (no spaces) of each event you want to track.
Note: I noticed you have events as an array. Fairly often I see clients do this (and also with linkTrackVars and linkTrackEvents), and then later on within the code (usually within s_doPlugins) have code that converts it to string (e.g. s.events=s.events.join();). It makes it easier to .push() values to it based on whatever logic you have, and this is fine, but to be clear, the official syntax is a comma delimited string, not array, so if you do it as an array, you need to ensure it is converted to a comma delimited string before the s.t or s.tl call. As an alternative, there is an s.apl plugin that handles appending values to the string, even ensuring it is unique in the string.
Examples:
Track event1,event2,prop55
s.prop55='some value';
s.events = 'event1,event2';
s.linkTrackEvents = 'event1,event2';
s.linkTrackVars = 'events,prop55';
Track event1 (serialized), event2, prop55
s.prop55='some value';
s.events = 'event1:12345,event2';
s.linkTrackEvents = 'event1,event2';
s.linkTrackVars = 'events,prop55';
Track event1 (custom increment), event2, prop55
s.prop55='some value';
s.events = 'event1=5,event2';
s.linkTrackEvents = 'event1,event2';
s.linkTrackVars = 'events,prop55';

Resources