loading value from element using xpath - xpath

I'm kinda new to xpath. So I don't know how to do this. I have this file
<map>
<object name="object (1)">
<position>564.014893 -7424.033691 35.448875</position>
<rotation>0.000000 0.000000 0.000000</rotation>
<model>3494</model>
</object>
</map>
As you can see in position;
564.014893 -7424.033691 35.448875
564.014893 is X
-7424.033691 is Y
35.448875 is Z
How do I load X(or Y/Z)?

If you have xpath 2 support, you can use tokenize to split the string on spaces. The X, Y and Z values would respectively be:
tokenize(map/object/position, ' ')[1]
tokenize(map/object/position, ' ')[2]
tokenize(map/object/position, ' ')[3]
If you only have xpath 1 support, you could use the substring-before and substring-after methods. The X, Y, and Z values would respectively be:
substring-before(map/object/position, " ")
substring-before(substring-after(map/object/position, " "), " ")
substring-after(substring-after(map/object/position, " "), " ")

Related

How can I call multiple values from the element with the same name with xpath?

I want the last two <dd> elements so that the output will read, Talstrasse 2A 01816 Berggiesshübel
here is the html snippet
<dt>Öffnungszeiten:</dt>
<dd>10:00 - 17:00</dd> <dt>Veranstaltungsart:</dt>
<dd> Herbstmarkt</dd> <dt>Veranstaltungsort:</dt>
<dd> Besucherbergwerk "Marie Louise Stolln" Berggiesshübel</dd> <dt>Strasse:</dt>
<dd>Talstrasse 2A,</dd>
<dt>PLZ / Ort:</dt>
<dd> 01816 Berggiesshübel </dd>
here is the suggested xpath my software gives me.
//div[contains(concat (" ", normalize-space(#class), " "), " container ")]/section[contains(concat (" ", normalize-space(#class), " "), " row event-details ")]/div[1]/div[3][contains(concat (" ", normalize-space(#class), " "), " bg-normal pal mbm ")]/div[1][contains(concat (" ", normalize-space(#class), " "), " row ")]/div[1]/dl[1][contains(concat (" ", normalize-space(#class), " "), " dl-horizontal event-detail-dl ")]/dd[6] | //html/body/div/section/div[1]/div[3]/div[1]/div[1]/dl[1]/dd[6]
can anyone help me?
The last two dd elements would be (//dd)[position() >= last() - 1]. In XPath 2.0 and higher you can get a single string using the string-join function e.g. string-join((//dd)[position() >= last() - 1], ' ').

Use repeat of format for many variables on the same line

puts "%-30s%2s%3d%2s%3d%2s%3d%2s%3d%2s%3d" % [tn,ln,a,ln,b,ln,c,ln,d,ln,e]
This is Ruby, but many languages use this formatting. I have forgotten how to output several variables in the same format, without repeating the format in each case. Here, I want "%3d%2s" for 5 integers, each separated by a '|'
You could write the following.
def print_my_string(tn, ln, *ints)
fmt = "%-10s" + ("|#{"%2s" % ln}%3d" * ints.size) + "|"
puts fmt % [tn, *ints]
end
Then, for example,
print_my_string("hello", "ho", 2, 77, 453, 61, 999)
displays
hello |ho 2|ho 77|ho453|ho 61|ho999|
after having computed
fmt = "%-10s" + ("|#{"%2s" % ln}%3d" * ints.size) + "|"
#=> %-10s|ho%3d|ho%3d|ho%3d|ho%3d|ho%3d|"

xpath how can I select elements that have a number inside text?

<span>Постов: 223 / Файлов: 10</span>
<span>Постов: 23 / Файлов: 0</span>
<span>Постов: 63 / Файлов: 6</span>
How can I select all spans containing number <99 after "Постов: "
I tried this
//span[contains(text(), "Постов: ") and number(substring(text(), 9, 3))<99]
The number you want appears after "Постов: " and before " /". So you can use substring-after() and substring-before().
//span[substring-before(substring-after(text(),'Постов: '),' /') < 99]

Expected: 0, instead got: 1 Ruby

I've been working on a task to create a function that returns the total number of smiley faces. Valid smiley faces look like: ":) :D ;-D :~)" and invalid smiling faces: ";( :> :} :] ".
My solution below throws the following error message "expected 0 instead got 1".
def count_smileys(arr)
arr.count do |element|
[":)", ":D", ";-D", ":~)", ";~D", "8~(", ";(", ":>", ":}", ":]",
"8~P", "8-(", "; )", ";-P", ":~P", "~P", ":~P", "~P", "; (", ":-)",
"8~D", "~)", "8D", "~)", "8 )", "; )", "~)", ":-D", " (", ";D",
"8-D", "8-P", ";-D", ": D", ";~D", " ("].include?(element)
end
end
As it stands my solution passes 4 out of 5 basic tests:
Basic tests
Test Passed: Value == 0
Test Passed: Value == 4
Test Passed: Value == 2
Test Passed: Value == 1
Expected: 0, instead got: 1
I've tried removing the parameters but that only worked for the last test and failed me on the rest. Any suggestions? Thanks
Example tests below:
Test.describe("Basic tests") do
Test.assert_equals(count_smileys([]), 0)
Test.assert_equals(count_smileys([":D",":~)",";~D",":)"]), 4)
Test.assert_equals(count_smileys([":)",":(",":D",":O",":;"]), 2)
Test.assert_equals(count_smileys([";]", ":[", ";*", ":$", ";-D"]), 1)
Test.assert_equals(count_smileys([";", ")", ";*", ":$", "8-D"]), 0)
end
Compare or Inspect Using Array Intersection
You don't show your actual test setup, so I won't address that. However, it seems like you're trying to count the number of smileys in a given array using the block form of Array#count. It's arguably simpler to measure the size of an Array intersection, or to inspect the contents of the intersection, using Array#&. For example:
SMILEYS = [
":)", ":D", ";-D", ":~)", ";~D", "8~(", ";(", ":>", ":}", ":]",
"8~P", "8-(", "; )", ";-P", ":~P", "~P", ":~P", "~P", "; (", ":-)",
"8~D", "~)", "8D", "~)", "8 )", "; )", "~)", ":-D", " (", ";D",
"8-D", "8-P", ";-D", ": D", ";~D", " ("
]
SMILEYS.&([":D", ":~)", ";~D", ":)"]).size == 4
#=> true
SMILEYS.&([":)", ":(", ":D", ":O", ":;"]).size == 2
#=> true
SMILEYS.&([";]", ":[", ";*", ":$", ";-D"]).size == 1
#=> true
SMILEYS.&([";", ")", ";*", ":$", "8-D"]).size == 0
#=> false
Note that the last comparison is false because 8-D is defined in your list of SMILEYS. Specifically:
SMILEYS.&([";", ")", ";*", ":$", "8-D"])
#=> ["8-D"]
so the expected value should be 1 unless 8-D doesn't really belong in your array of acceptable values. If that's the case, remove it from the variable or constant containing your allowable values.

Get number first and second and third from text line

I have the following format in my txt file:
1 1,30705856804525E-7 2,64163961816166E-8
1,12201845645905 1,24157281788939E-7 2,45690063849224E-8
1,25892543792725 1,18248813407718E-7 2,29960868125545E-8
1,41253757476807 1,13006606738963E-7 2,16654658657944E-8
1,58489322662354 1,0842624220686E-7 2,05472137082552E-8
1,77827942371368 1,04479198625995E-7 1,96135836461053E-8
1,99526226520538 1,01119816520168E-7 1,8839035220708E-8
2,23872113227844 9,82917924829962E-8 1,82003176973922E-8
2,51188635826111 9,59338279926669E-8 1,76765304615856E-8
2,81838297843933 9,39840489877497E-8 1,72491425587395E-8
3,16227769851685 9,23831819932275E-8 1,69019571671924E-8
3,54813385009766 9,10766573269939E-8 1,66210121221866E-8
3,98107171058655 9,00157104410937E-8 1,63944182673958E-8
4,46683597564697 8,91577514039454E-8 1,62121711611007E-8
5,01187229156494 8,8466336478632E-8 1,60659361370108E-8
5,6234130859375 8,7910699164695E-8 1,59488209305891E-8
6,30957365036011 8,74651959748007E-8 1,58551749507296E-8
7,07945775985718 8,71086527354237E-8 1,57803938805046E-8
7,94328212738037 8,68237393092386E-8 1,57207402651238E-8
8,91250896453857 8,65963372120859E-8 1,56731942979604E-8
10 8,64150138113473E-8 1,56353241465013E-8
11,2201843261719 8,62705391568852E-8 1,5605175818223E-8
I need to get only value for integers on left and right value so in this example I need to get:
1
2,64163961816166E-8
10
1,56353241465013E-8
This is what I've tried:
' Check Noise Spectral Density.txt exists
Set fso = CreateObject("Scripting.FileSystemObject")
If (fso.FileExists(fso.GetParentFolderName(WScript.ScriptFullName) + "\Projects\Noise Spectral Density.txt")) Then
' Open the file for input.
Set NoiseSpectralDensity = fso.OpenTextFile(fso.GetParentFolderName(WScript.ScriptFullName) + "\Projects\Noise Spectral Density.txt", 1)
' Noise Variables
Dim Noise
' Read from the file and display the results.
Do While NoiseSpectralDensity.AtEndOfStream <> True
' Read Line By Line
TextLine = NoiseSpectralDensity.ReadLine
' Check If Number
'If (IsNumeric(Left(TextLine, 5))) Then
' Get Noise
' Noise # 1kHz
Noise = Right(TextLine, InStr(Mid(TextLine, 2), InStr(TextLine, " ")-1))
x = MsgBox("SNR: " & Split(Left(TextLine, 5), " ")(0) & " NOISE: " & Noise & "",0, "Noise Spectral Density")
'End If
Loop
' Close the file for input.
NoiseSpectralDensity.Close
Else
x = MsgBox("Noise Spectral Density.txt NOT Found!" & vbCrLf & "Wave->Save As Text...", 0, "Noise Spectral Density")
End If
But I could not get left and right numbers in VBScript using Split(TextLine, " ")(0).
Your data seems to be tab-separated, so you could do something like this:
arr = Split(TextLine, vbTab)
If Not (InStr(arr(0), ",") > 0) Then
'first number doesn't have decimals
snr = arr(0)
noise = arr(2)
End If
Though the solution provided by #AnsgarWiechers should work but in case, if it doesn't, you can make use of regular expressions(Replace the whole Do-while loop with the following):
Set objReg = New RegExp
objReg.Pattern = "^(\d+)(?=\s).*\s+([\d,Ee-]+)$" 'See the explanation below
Do While NoiseSpectralDensity.AtEndOfStream <> True
'Read Line By Line
TextLine = NoiseSpectralDensity.ReadLine
' Check If Number
Set objMatches = objReg.Execute(TextLine)
For Each objMatch In objMatches
SNR = objMatch.submatches.item(0)
Noise = objMatch.submatches.item(1)
MsgBox "SNR: "&SNR&"; Noise: "&Noise
Next
Loop
Click for Regex Demo
Regex Explanation:
^ - asserts the start of the string
(\d+) - matches 1+ occurrences of a digit and captures it in Group 1
(?=\s) - positive lookahead to find the position immediately preceded by a white-space. So the digits in the step 2 will be matched until a whitespace(spaces,tabs etc.) is encountered
.* - matches 0+ occurrences of any character except a newline
\s+ - matches 1+ occurrences of a whitespace
([\d,Ee-]+) - matches 1+ occurrences of a digit or , or - or the letter E or e and capture it in group 2
$ - asserts the end of the string

Resources