Can I combine captures in Sublime Text syntax? - sublimetext3

I'm writing the syntax for V which defines methods with a similar syntax to Go, where:
fn (o MyStruct) my_function(a int) {
// ...
}
I might use something like (I will break it down into push, but just for brevity):
variables:
ident: \b[A-Za-z_][A-Za-z_0-9]*\b
contexts:
fn:
- match: (fn)\s*\({{ident}}\s*({{ident}})\)\s*({{ident}})
captures:
1: keyword
2: entity.name.type.v
3: entity.name.function.v
But the problem is MyStruct and my_function are indexed separately, so methods of the same name (str() is a good example) will not be distinct to the indexer. Is there a way I can combine them into a single entity.name.function.v of value MyStruct.my_function?
I know I could treat the whole definition as the entity, but that's too verbose and won't work when split across multiple lines:
captures:
0: entity.name.function.v

If you apply an unbroken/continuous scope to the text, you can target that in a .tmPreferences file (as opposed to the default entity.name scope) and index that, and make use of a "symbol index transformation" to remove the ) and spaces.
- match: (fn)\s*\({{ident}}\s*(({{ident}})\)\s*({{ident}}))
captures:
1: keyword
2: meta.indexed-unit.v
3: entity.name.type.v
4: entity.name.function.v
Now the scope meta.indexed-unit.v would apply to the text MyStruct) my_function.
A symbol index transformation is basically a regex replacement which applies to the indexed symbols:
https://docs.sublimetext.io/reference/symbols.html#settings-subelements
So your .tmPreferences file might look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>scope</key>
<string>source.v meta.indexed-unit.v</string>
<key>settings</key>
<dict>
<key>showInIndexedSymbolList</key>
<string>1</string>
<key>symbolIndexTransformation</key>
<string>
s/\)\s*//;
</string>
</dict>
</dict>
</plist>

Related

NIFI - EvaluateXPath to use as attribute - values

I have an xml that I need to extract the value of nCT and serie.
<?xml version="1.0" encoding="UTF-8"?>
<cteProc xmlns="http://www.portalfiscal.inf.br/cte" versao="3.00">
<CTe>
<infCte Id="CTe41221100428307001240570010023982451023982450" versao="3.00">
<ide>
<serie>1</serie>
<nCT>2398245</nCT>
<dhEmi>2022-11-04T19:24:16-03:00</dhEmi>
I need to create an attribute with evaluateXPath processor to extract this 'nCT' and 'serie' as text.

Reading CDATA with lxml, problem with end of line

Hello I am parsing a xml document with contains bunch of CDATA sections. I was working with no problems till now. I realised that when I am reading the an element and getting the text abribute I am getting end of line characters at the beggining and also at the end of the text read it.
A piece of the important code as follow:
for comments in self.xml.iter("Comments"):
for comment in comments.iter("Comment"):
description = comment.get('Description')
if language == "Arab":
tag = self.name + description
text = comment.text
The problem is at element Comment, he is made it as follow:
<Comment>
<![CDATA[Usually made it with not reason]]>
I try to get the text atribute and I am getting like that:
\nUsually made it with not reason\n
I Know that I could do a strip and so on. But I would like to fix the problem from the root cause, and maybe there is some option before to parse with elementree.
When I am parsing the xml file I am doing like that:
tree = ET.parse(xml)
Minimal reproducible example
import xml.etree.ElementTree as ET
filename = test.xml #Place here your path test xml file
tree = ET.parse(filename)
root = tree.getroot()
Description = root[0]
text = Description.text
print (text)
Minimal xml file
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Description>
<![CDATA[Hello world]]>
</Description>
You're getting newline characters because there are newline characters:
<Comment>
<![CDATA[Usually made it with not reason]]>
</Comment>
Why else would <![CDATA and </Comment start on new lines?
If you don't want newline characters, remove them:
<Comment><![CDATA[Usually made it with not reason]]></Comment>
Everything inside an element counts towards its string value.
<![CDATA[...]]> is not an element, it's a parser flag. It changes how the XML parser is reading the enclosed characters. You can have multiple CDATA sections in the same element, switching between "regular mode" and "cdata mode" at will:
<Comment>normal text <![CDATA[
CDATA mode, this may contain <unescaped> Characters!
]]> now normal text again
<![CDATA[more special text]]> now normal text again
</Comment>
Any newlines before and after a CDATA section count towards the "normal text" section. When the parser reads this, it will create one long string consisting of the individual parts:
normal text
CDATA mode, this may contain <unescaped> Characters!
now normal text again
more special text now normal text again
I thought that when CDATA comes at xml they were coming with end of line at the beginning and at the end, like that.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Description>
<![CDATA[Hello world]]>
</Description>
But you can have it like that also.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Description><![CDATA[Hello world]]></Description>
It is the reason to get end of line characters when we are parsing the with the Elementtree library, is working perfect in both cases, you only have to strip or not strip depending how you want to process the data.
if you want to remove both '\n' just add the following code:
text = Description.text
text = text.strip('\n')

To remove array string item from config file

How to remove a string array item from the config file?
<configuration>
<applicationSettings>
<Sample.Service.Properties.Settings>
<setting name="SampleAttribute" serializeAs="Xml">
<value>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>firstemail#domain.com</string>
<string>secondemail#domain.com</string>
</ArrayOfString>
</value>
I am able to access the first item (firstemail#domain.com) from the config file and can replace the value by the following code.
But my question is how to remove the second item(secondemail#domain.com) from the config file through following similar code.
{
"configuration/applicationSettings/Sample.Service.Properties.Settings/setting[#name='SampleAttribute']/value/ArrayOfString/string[0]":"$(SampleAttribute)"
}
To remove array string item from config file
I am afraid we could not use the File Transform (not sure whether the Config Transform you said is file Transform or Config Transformation) to remove the array string item.
To resolve this issue, you could use the task Replace Tokens to replace the first item and remove the second item:
The format of variable in config file is #{EmailOne}# & #{EmailTwo}#.
My test config file like:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<applicationSettings>
<Sample.Service.Properties.Settings>
<setting name="SampleAttribute" serializeAs="Xml">
<value>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>#{EmailOne}#</string>
#{EmailTwo}#
</ArrayOfString>
</value>
</setting>
</Sample.Service.Properties.Settings>
</applicationSettings>
</configuration>
Then we just need to define the variable EmailOne and EmailTwo in the Variables with replace value and empty value:
The test result:
Inline Powershell Scripts:
$appConfigFile = "$(System.DefaultWorkingDirectory)\xxx\xxx\web.config" #change the path to your config file.
$appConfig = New-Object XML
$appConfig.Load($appConfigFile)
foreach($BuildNumber in $appConfig.configuration.applicationSettings."Sample.Service.Properties.Settings".setting.value.ArrayOfString)
{
$BuildNumber.RemoveChild($BuildNumber.FirstChild.NextSibling)
}
$appConfig.Save($appConfigFile)

Groovy: replaceLast() is missing

I need replaceLast() method in the Groovy script - replace the last substring. It is available in Java, but not in Groovy AFAIK. It must work with regex in the same way as the following replaceFirst.
replaceFirst(CharSequence self, Pattern pattern, CharSequence replacement)
Replaces the first substring of a CharSequence that matches the given compiled regular expression with the given replacement.
EDIT: Sorry not being specific enough. Original string is an XML file and the same key (e.g. Name) is present many times. I want to replace the last one.
<Header>
<TransactionId>1</TransactionId>
<SessionId>1</SessionId>
<User>
<Name>Bob</Name>
...
</User>
<Sender>
<Name>Joe</Name>
...
</Sender>
</Header>
...
<Context>
<Name>Rose</Name>
...
</Context>
No idea what replaceLast in Java is...it's not in the JDK... If it was in the JDK, you could use it in Groovy...
Anyway, how about using an XML parser to change your XML instead of using a regular expression?
Given some xml:
def xml = '''<Header>
<TransactionId>1</TransactionId>
<SessionId>1</SessionId>
<User>
<Name>Bob</Name>
</User>
<Sender>
<Name>Joe</Name>
</Sender>
<Something>
<Name>Tim</Name>
</Something>
</Header>'''
You can parse it using Groovy's XmlParser:
import groovy.xml.*
def parsed = new XmlParser().parseText(xml)
Then, you can do a depth first search for all nodes with the name Name, and take the last -1 one:
def lastNameNode = parsed.'**'.findAll { it.name() == 'Name' }[-1]
Then, set the value to a new string:
lastNameNode.value = 'Yates'
And print the new XML:
println XmlUtil.serialize(parsed)
<?xml version="1.0" encoding="UTF-8"?><Header>
<TransactionId>1</TransactionId>
<SessionId>1</SessionId>
<User>
<Name>Bob</Name>
</User>
<Sender>
<Name>Joe</Name>
</Sender>
<Something>
<Name>Yates</Name>
</Something>
</Header>

Swift String encoding and NSXMLParser parsing issues

My App is calling the free Weather Forecast web service found at this URL:
http://www.webservicex.net/globalweather.asmx/GetWeather?CityName=Boston&CountryName=United+States
I'm using the usual NSURLConnection and NSXMLParser delegate methods to parse the incoming data (I've done this a million times before) but quite strangely, the NSMutableData that is returned is not getting converted to a string correctly via NSUTF8StringEncoding. Its basically failing to convert the "<" and ">" characters of the opening and closing XML tags, giving me "& l t;" and "& g t;" instead.
The problem seems to be in the connectionDidFinishLoading function:
func connection(connection: NSURLConnection, didReceiveData data: NSData) {
webServiceData!.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection) {
let XMLResponseString = NSString(data: webServiceData!, encoding: NSUTF8StringEncoding)!
println("XMLResponseString = \(XMLResponseString)")
}
The output I get from the println statement there is:
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://www.webserviceX.NET"><?xml version="1.0" encoding="utf-16"?>
<CurrentWeather>
<Location>DALLAS EXECUTIVE AIRPORT, TX, United States (KRBD) 32-41N 096-52W 203M</Location>
<Time>Dec 30, 2014 - 08:53 AM EST / 2014.12.30 1353 UTC</Time>
<Wind> from the NE (050 degrees) at 12 MPH (10 KT):0</Wind>
<Visibility> 9 mile(s):0</Visibility>
<SkyConditions> overcast</SkyConditions>
<Temperature> 39.9 F (4.4 C)</Temperature>
<DewPoint> 34.0 F (1.1 C)</DewPoint>
<RelativeHumidity> 79%</RelativeHumidity>
<Pressure> 30.42 in. Hg (1030 hPa)</Pressure>
<Status>Success</Status>
</CurrentWeather></string>
So as you can see I'm getting the first 2 tags correctly - the "< ?XML >" and "< string xmlns >" tags, but the rest are all showing up as "& l t;" and "& g t;"
What's really strange is that its saying encoding="utf-8" for the first tag, but on the second line (towards the end) its saying encoding="utf-16".
So I tried using NSUTF16StringEncoding:
let XMLResponseString = NSString(data: webServiceData!, encoding: NSUTF16StringEncoding)!
and that basically gave me chinese looking characters.
I also tried running the parser directly on the url instead of the NSMutableData that's returned, like so:
myXMLParser = NSXMLParser(contentsOfURL:theURL!)!
(the original statement was this:
myXMLParser = NSXMLParser(data:webServiceData)
but neither of these worked.
So what's going on here? Any suggestions on how to get this to work properly?
This is actually the remote service being broken, rather than your code. Yes, the server really is sending XML in XML for no particularly good reason.
$ curl 'http://www.webservicex.net/globalweather.asmx/GetWeather?CityName=Boston&CountryName=United+States'
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://www.webserviceX.NET"><?xml version="1.0" encoding="utf-16"?>
<CurrentWeather>
<Location>BOSTON LOGAN INTERNATIONAL, MA, United States (KBOS) 42-22N 071-01W 54M</Location>

Resources