I would like to parse my XML string using an XQJ implementation, for example, SAXON. All examples I could find refer to some database connections. Is it possible to use simple String as xml source?
Saxon has an XQJ interface, and you could either use the doc function() from XQuery e.g. :
XQDataSource ds = new SaxonXQDataSource();
XQConnection conn = ds.getConnection();
XQPreparedExpression exp = conn.prepareExpression("doc('file:/some/file.xml')/child::node()");
XQResultSequence result = exp.executeQuery();
while(result.next()) {
System.out.println(result.getItemAsString(null));
}
or directly inject in the XML into the query. e.g. -
XQDataSource ds = new SaxonXQDataSource();
XQConnection conn = ds.getConnection();
XQPreparedExpression exp = conn.prepareExpression("<a><b>test</b></a>/child::node()");
XQResultSequence result = exp.executeQuery();
while(result.next()) {
System.out.println(result.getItemAsString(null));
}
Try using
void XQExpression.bindDocument(javax.xml.namespace.QName varName, javax.xml.transform.Source value, XQItemType type)
with XQConstants.CONTEXT_ITEM as the first argument, and a StreamSource wrapping a StringReadeer as the second.
Related
<AspResp errCode="NA" errMsg="NA" status="1" transId="6c8c5901-6119-4c59-89ce-b3f9efb141f2">
<EResp errCode="NA" errMsg="NA" resCode="ea3229b1-c9ff-455b-8d3f-84a4c2384c85" status="1" ts="2020-04-27T15:00:10.947" txn="90f4f36f-7051-4c6d-bed4-bd717ddfa38d">
<Signatures>
<DocSignature error="NA" id="1">test</DocSignature>
</Signatures>
</EResp>
</AspResp>
I want value of transId from first node in the above XML.
I used this code but it is useless
foreach (XElement hashElement in doc.Descendants("transId"))
{
hashValue = (string)hashElement;
}
Select required node. Since transId is an attribute, you should access like this:
string attrtransId = node.Attributes["transId"].value
Take a look at this, It's very detailed & easy to understand.
How do I read and parse an XML file in C#?
string XMLText = #"<AspResp errCode='NA' errMsg='NA' status='1' transId='6c8c5901-6119-4c59-89ce-b3f9efb141f2'><EResp errCode='NA' errMsg='NA' resCode='ea3229b1-c9ff-455b-8d3f-84a4c2384c85' status='1' ts='2020-04-27T15:00:10.947' txn='90f4f36f-7051-4c6d-bed4-bd717ddfa38d'><Signatures><DocSignature error='NA' id='1'>test</DocSignature></Signatures></EResp></AspResp>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(XMLText);
XmlNode node = doc.GetElementsByTagName("AspResp")[0];
string transId = node.Attributes["transId"].Value;
Tested xpath with http://xpather.com/2S8920tn
string XMLText =
#"<AspResp errCode='NA' errMsg='NA' status='1' transId='6c8c5901-6119-4c59-89ce-b3f9efb141f2'><EResp errCode='NA' errMsg='NA' resCode='ea3229b1-c9ff-455b-8d3f-84a4c2384c85' status='1' ts='2020-04-27T15:00:10.947' txn='90f4f36f-7051-4c6d-bed4-bd717ddfa38d'><Signatures><DocSignature error='NA' id='1'>test</DocSignature></Signatures></EResp></AspResp>";
var doc = XDocument.Parse(XMLText);
string transId = doc.XPathSelectElement("/node()[1]").Attribute("transId")?.Value;
I am using asp.net. I am trying to split the data which is in datatable. I have a code sample like this:
{ dt=objErrorLoggingDataAccess.GetErrorDetails(errorID);
string[] stringSeparators = new string[] { "Message" };
string error = dt.Rows[0]["Message"].ToString();
string[] test = error.Split(stringSeparators, StringSplitOptions.None);
string PageName = test[0].ToString();
PageNameLabel.Text = PageName;
stringSeparators=new string[] {HttpContext.Current.Request.Url.ToString()};
error = dt.Rows[0]["Message"].ToString();
test = error.Split(stringSeparators, StringSplitOptions.None);
string Message = test[0].ToString();
MessageLabel.Text = Message;}
in the datatable following data is there:
{....ID.......Message.......................................................................................................................
....1........http://localhost:10489/images/CategoryIcon/images Message : File does not exist. UserName: naresh#naresh.com
....2........http://localhost:10489/images/CategoryIcon/images Message : File does not exist. UserName: iswar#iswar.com}
My problem is: how can I split the Message and store in the label? I want
{http://localhost:10489/images/CategoryIcon/images}
separately and UserName separately and the message separately. How can I do that? By executing the above code I am able to split
{ http://localhost:10489/images/CategoryIcon/images
}
only. How can I split the Message column and store in pageLabel, MessageLabel, UserNamelabel?
I would use a regular expression in this case. Because only by splitting this string looks a little bit to inflexible to me.
I tested your data example against this quick and dirty RegEx:
(?<id>\d+)\.*(?<url>\w+:\/\/[\w#][\w.:#]+\/?[\w\.?=%&=\-#/$,]*)\s*Message\s*:\s*(?<message>.*)UserName:\s*(?<username>([a-zA-Z0-9_\-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3}))
It supports valid URLs and EMail patterns.
Regex regex = new Regex(
"(?<id>\\d+)\\.*(?<url>\\w+:\\/\\/[\\w#][\\w.:#]+\\/?[\\w\\.?"+
"=%&=\\-#/$,]*)\\s*Message\\s*:\\s*(?<message>.*)UserName:\\s"+
"*(?<username>([a-zA-Z0-9_\\-\\.]+)#((\\[[0-9]{1,3}\\.[0-9]{1"+
",3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|"+
"[0-9]{1,3}))",
RegexOptions.IgnoreCase
| RegexOptions.CultureInvariant
| RegexOptions.IgnorePatternWhitespace
| RegexOptions.Compiled
);
// Capture the first Match, if any, in the InputText
Match m = regex.Match(InputText);
// Capture all Matches in the InputText
MatchCollection ms = regex.Matches(InputText);
// Test to see if there is a match in the InputText
bool IsMatch = regex.IsMatch(InputText);
// Get the names of all the named capture groups
// I included your fields as groups: id, url, message and username
string[] GroupNames = regex.GetGroupNames();
I don't know how often you need to call this code. Maybe you get in performance troubles if you have too much data. This regex is q&d - please adjust it to your needs.
I was using as3Crypto with no probs
http://www.zedia.net/2009/as3crypto-and-php-what-a-fun-ride/
but then I saw some special characters and I realised I could encounter ampersands.
Which is a pain because they will be inserted into a query string.
Is there a way to ensure the as3Crypto encryption does not produce ampersands?
public function encrypt(txt:String = ''):String
{
var data:ByteArray = Hex.toArray(Hex.fromString(txt));
var pad:IPad = new PKCS5;
var mode:ICipher = Crypto.getCipher(type, key, pad);
pad.setBlockSize(mode.getBlockSize());
mode.encrypt(data);
return ''+Base64.encodeByteArray(data);
}
Assuming a standard base64 implementation, Base64.encodeByteArray(data); will not produce ampersands.
I'm trying to parse an RSS feed using LINQ to Xml
This is the rss feed:
http://www.surfersvillage.com/rss/rss.xml
My code is as follows to try and parse
List<RSS> results = null;
XNamespace ns = "http://purl.org/rss/1.0/";
XNamespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
XDocument xdoc = XDocument.Load("http://www.surfersvillage.com/rss/rss.xml");
results = (from feed in xdoc.Descendants(rdf + "item")
orderby int.Parse(feed.Element("guid").Value) descending
let desc = feed.Element("description").Value
select new RSS
{
Title = feed.Element("title").Value,
Description = desc,
Link = feed.Element("link").Value
}).Take(10).ToList();
To test the code I've put a breakpoint in on the first line of the Linq query and tested it in the intermediate window with the following:
xdoc.Element(ns + "channel");
This works and returns an object as expect
i type in:
xdoc.Element(ns + "item");
the above worked and returned a single object but I'm looking for all the items
so i typed in..
xdoc.Elements(ns + "item");
This return nothing even though there are over 10 items, the decendants method doesnt work either and also returned null.
Could anyone give me a few pointers to where I'm going wrong? I've tried substituting the rdf in front as well for the namespace.
Thanks
You are referencing the wrong namespace. All the elements are using the default namespace rather than the rdf, so you code should be as follow:
List<RSS> results = null;
XNamespace ns = "http://purl.org/rss/1.0/";
XDocument xdoc = XDocument.Load("http://www.surfersvillage.com/rss/rss.xml");
results = (from feed in xdoc.Descendants(ns + "item")
orderby int.Parse(feed.Element(ns + "guid").Value) descending
let desc = feed.Element(ns + "description").Value
select new RSS
{
Title = feed.Element(ns + "title").Value,
Description = desc,
Link = feed.Element(ns + "link").Value
}).Take(10).ToList();
Ok now for the juicy stuff. All attempts failed to save my string so far.
Here is the code for saving it in sqllite in firefox extension:
var file = Components.classes["#mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("ProfD", Components.interfaces.nsIFile);
file.append("my_db_file_name.sqlite");
var storageService = Components.classes["#mozilla.org/storage/service;1"]
.getService(Components.interfaces.mozIStorageService);
var mDBConn = storageService.openDatabase(file);
mDBConn.execute("CREATE TABLE IF NOT EXISTS log_det (id INTEGER PRIMARY KEY AUTOINCREMENT, acc STRING)");
mDBConn.execute("INSERT INTO log_det (acc) VALUES(" + window['gluistr']+ ")");
mDBConn.drop();
And the code for retrieving the value:
var file = Components.classes["#mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("ProfD", Components.interfaces.nsIFile);
file.append("my_db_file_name.sqlite");
var storageService = Components.classes["#mozilla.org/storage/service;1"]
.getService(Components.interfaces.mozIStorageService);
var mDBConn = storageService.openDatabase(file);
var res = mDBConn.execute("SELECT * FROM log_det");
mDBConn.drop();
Is not working. Anybody knows why? Is "execute" ok or do I need "createStatement" or "executeSimpleSQL". I am confused.
Use executeSimpleSQL.
openDatabase returns a mozIStorageConnection instance, which does not have any method named execute. You can use executeSimpleSQL any time you want to execute a SQL statement without bound parameters (which is what you're doing).
You were probably thinking of mozIStorageStatement's execute method. executeSimpleSQL is not sufficient when bound parameters are necessary. Instead, you need to create a statement, bind any parameters, and then execute it:
var statement = mDBConn.createStatement(
"SELECT * FROM log_det WHERE column_name = :parameter");
statement.bindStringParameter(0, "value");
statement.execute();
statement.reset();
Also note that mozIStorageConnection does not have any method named drop. Maybe you meant to write mDBConn.close()?
All of this is covered here:
https://developer.mozilla.org/en/storage