Skip to content

Instantly share code, notes, and snippets.

@dhval
Last active July 5, 2024 14:20
Show Gist options
  • Save dhval/49aedf8aee5412c7cd906e96a6d8f601 to your computer and use it in GitHub Desktop.
Save dhval/49aedf8aee5412c7cd906e96a6d8f601 to your computer and use it in GitHub Desktop.
Git Cheat Sheet

Open VSCode remote ssh workspace.

 code --file-uri "vscode-remote://ssh-remote+jnet/C:/workspace/vscode-workspace.code-workspace"

OSX App's Icon stuck

killall Dock

Create and build application

dotnet new console -n JnetClient
dotnet build | restore
dotnet build -r win10-x64
dotnet publish -c Debug -r win10-x64

dotnet run --project WSSClient.csproj "arg"

dotnet warp

dotnet tool install --global dotnet-warp --version 1.1.0

dotnet cli

NuGet dependencies

dotnet add package System.Security.Cryptography.Xml --version 4.5.0
dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.Binder
dotnet add package Microsoft.Extensions.Configuration.FileExtensions
dotnet add package Microsoft.Extensions.Configuration.Json
dotnet add package Microsoft.Extensions.Configuration.EnvironmentVariables

Choco

Install or Upgrade a package

choco install microsoft-windows-terminal

Azure

PS Finding Stuff

Get-Command -Verb Get -Noun Az* -Module Az*
Get-Command -Verb Publish -Noun Az* -Module Az*
Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted

Get-PSRepository
Get-PackageProvider -ListAvailable 
Install-PackageProvider -Name "NuGet"
Get-Module -Name PowerShellGet -ListAvailable | Install-Module
Get-Module -Name PowerShellGet -ListAvailable | Select-Object -Property Name,Version,Path
Install-Module -Name Az -AllowClobber -Scope AllUsers -Verbose

Resources

  • webapp list
  • appservice plan list
Example
APPNAME=$(az webapp list --query [0].name --output tsv)
APPRG=$(az webapp list --query [0].resourceGroup --output tsv)
APPPLAN=$(az appservice plan list --query [0].name --output tsv)
APPSKU=$(az appservice plan list --query [0].sku.name --output tsv)
APPLOCATION=$(az appservice plan list --query [0].location --output tsv)

az webapp up --name $APPNAME --resource-group $APPRG --plan $APPPLAN --sku $APPSKU --location "$APPLOCATION"

az webapp log tail --resource-group BestBikes20190819020856ResourceGroup --name BestBikes20190819020856
az webapp log show --resource-group BestBikes20190819020856ResourceGroup --name BestBikes20190819020856

webapp

  1. PS-az websites

  2. PS_Publish-AzWebApp

  3. install az cli

portal.azure.com

Syntax Description
HEAD~2 --> HEAD^^ --> head@{2} Head
commit -a -m 'Oh dear' Add and commit
diff --name-only HEAD~1 HEAD~2 List changes files between commits
log --stat -n What changed -n is the number of commits to go back
checkout feature9 app/avi.rb app/hero.rb Checkout individual files from another branch
git clean -d -x -n Reset directory(-d); ignored files(-x); -f force; -n dry-run
  • Remove staged file git reset myfile.txt
  • Show Log git log --oneline --graph --all --decorate

  • List git ls-files --deleted --ignored --exclude-standard
  • List deleted files git rev-list -n 1 HEAD -- [deleted-filename]

  • Diff git diff --name-only
  • Diff Current Working Directory git diff -u .

  • Add certain file types in sub-directories git add local/**/\*.xsl

  • Checkout work tree in top directory git worktree add <path> <branch> & git worktree remove [-f] <path>
  • Push all local branches git push --all -u
  • Push local branch to remote git push -u origin guardianship-audit-logging-fix

Alias

alias ga="git add"
alias gs="git status"
alias gc="git commit -m"
alias gh="echo 'My Last 10 branches' && git for-each-ref --sort=-committerdate --format='%(committerdate:relative) %(refname:short)' refs/heads | head -n 11"

Config git config <option> [--global]

git config --global alias.ci 'commit -m "."'
git config -e 
  • Keep everything group read/writable core.sharedrepository 1
  • Must merge code on local machine and then push receive.denyNonFastforwards true
  • Remove executable bit core.filemode false
  • Line endings core.autocrlf false
  • Convert LF --> CRLF on checkout, Win OS core.autocrlf true
  • Convert CRLF --> LF on commit, Mac OS core.autocrlf input
  • To ignore whitespace apply.whitespace no warn
  • Tells git-branch and git-checkout to setup new branches branch.autosetupmerge true

Mapping .git directory

  • Use different path git -C "/home/domain/" status
  • Initialize a new separate folder git init --separate-git-dir /path/to/repo.git
  • Explicitly point to git directory git --git-dir=../repo --work-tree=. add foo
  • Alternatively export GIT_WORK_TREE=. and GIT_DIR=../backup
Proxies
git config http.proxy socks5h://192.168.1.47:9786
git -c http.proxy=socks5h://192.168.1.47:9786 clone https://url
[http]
        proxy = socks5h://192.168.1.47:9786  

Branch

--verbose --all --remote --local

  • Currently tracked remote branch git remote -v
  • Show remote branches git ls-remote
  • Create & checkout branch git checkout -b feature/mytask
  • Rename git branch -m feature/my-new-name
  • Delete git branch -d |-D feature/mybranch
  • Delete remote branch git push origin :feature/mybranch

Fetch & Pull

git pull is the combination of git fetch + git merge.

git fetch
git log FETCH_HEAD
git diff origin

Tip. You can always refer to a specific remote: git fetch origin develop. Works in more commands like: git pull, git diff...

Rebase & Merge

Merge will merge others changes with your changes as they happen, in logged order. Rebase will rewind your changes to a common known/shared commit, then apply the remote changes then apply your changes.

At develop: git pull develop
At your feature: git rebase develop

Tip Try git rebase -i develop.

You can also do stuff like: git pull --rebase if you are collaborating with others on the same feature branch. On develop and master, this should not be needed.

Fast forward

When merging, if fast forward is possible, then that is the default strategy. That means, your changes can be added on top (appended last in the log) and the header (reflog) can be switched to point to your last commit.

At develop: git merge feature/myfeature -m 'Close #32'

If you do want to force a non fast forward, so that you e.g. see how your feature branch is merged back into develop:

At develop: git merge --no-ff feature/myfeature -m 'Close #32'

Stash

[Stash](https://git-scm.com/docs/git-stash)

--index = When you have working changes and want to get those changes reset but kept, you can stash (or put them in a branch):

git stash
git stash list
git stash pop
git stash apply --index
git stash push -m file.txt
git diff stash@{1} -- path-2-diff

There are more commands to stash. E.g. the destructive git stash clear. Inspect the documentation/help.

Diff

Syntax Description
--diff-filter=M only modified files
-w -b ignore whitespaces
git diff (same as: git diff HEAD)
git diff --staged
git diff develop
git diff HEAD^
git diff master
git diff 0659bdc e6c7c0d -- src/file.py

Creating a repo

  • Local cd foo_project && git init && git add * && git commit -m "init"
git remote add origin ssh://git@myhost/user/git-repos/foo.git
git push -u origin master
  • Remote cd git/foo-project.git && git --bare init

Resources

Git scm documentation Apply Patch Interative Merge

  • Git delete all branches except master git branch | grep -v "master" | xargs git branch -D

⌘ | ⌥ | ⇧ | ⌃ | → | ←

Cloud 9

Shortcut Description
⌘ + B Toggle Tree Sidebar
⌘ + J Show/Hide Terminal
⌘ + / Toggle Comment
⌘ + ⇧ + / Toggle Block Comment
⌘ + ⇧ + B Format File
⌘ + ⇧ + C Copy file Location
⌘ + ⇧ + L Show file Location in tree
Tab Navigation
⌘ + ] Next Tab
⌘ + [ Previous Tab
⌥ + W Close Tab

VSCode

  • Use ctrl (⌃) instead of for ⌘ windows.
  • The cord command (^ + K)
Shortcut Description
⌘ + B Toggle Tree Sidebar
⌘ + J Show/Hide Terminal
⌘ + P Open Recent File
⌘ + O Open Explorer to open file
⌘ + ⇧ + P Command Palette
⌘ + K + ⌘ + S Open keyboard shortcuts
⌘ + W X-- Close Editor Tab
Tab Navigation
⌘ + K + W Close Tab
⌥ + 0..9 Navigate SideBar/Editor/Results Pane
⌥ + PageUP Next Tab - View: Open Next Editor
⌃ + ⌥ + → Move current window to right Tab
⌃ + ⇧ + →PageUP Move current Tab left
*⌘ + * Split Vertical
*⌘ + K + ⌘ + * Split Horizontal
⌃ + Fn + Home X-- Close Tab
File Menu Navigation
⌘ + K + P Copy file path
⌘ + K + ⌘ + Q Last Edit Location
*⌘ + ⇧ + F X-- Format
⌘ + ⌥ + ⇧ + X X-- XPath Search
⌘ + K + ⌘ + C X-- Copy file path
Editing Navigation
⌃ + ⇧ + ] Expand Selection
⌃ + ⇧ + [ Shrink Selection
⌥ + ↑ Move Line Up
Terminal Navigation
⌘ + ` Toggle On/Off
*⌘ + ⇧ + ` New Terminal
Markdown Navigation
⌃ + ⇧ + O Jump to a header '#'.
*⌃ + ⇧ + V Show Preview

IntelliJ

Shortcut Description
⌘ + O Open command palette.
⌘ + E Recent Files.
⌘ + ⇧ + F12 Maximize editor - Show/Hide tool windows. F10
⌘ + } Next Tab { Previous Tab
⌘ + ] Next Place
⌘ + / Toggle Comment
⌘ + ⇧ + / Toggle Block Comment
⌥ + F12 Toggle Terminal - F12 show terminal
⌘ + , Open preferences
Ctrl + ⌥+ L Reformat

TMUX

Shortcut Description
attach, ls, d attach, list, detach
d Open Recent File
:send-keys Ctrl-c Command Pallete
, Rename Pane
$ Rename Session
⌘ + ⇧ + B Format File
⌘ + ⇧ + L Show file Location in tree

|Tab|Navigation| |:----------- -|:-----------------------------| |ctrl + ` | Togggle focus Editor/Terminal| |ctrl + num| Move to Editor Tab | |⌘ + J | Show/Hide Terminal | |⌘ + B | Show/Hide Tree | |ctrl + / | Focus next terminal |

Ctrl+Tab

The switcher | ⌘  + 0 - Commit | 1 - Project | 2 - Favorites | 9 - Git View

Open class (or file ) in the editor.

Manual -r Ignore result format -f read filter from file |= Passes the values

Filter .items array, select & print id from file .json

jq -r --arg id "$id"  '.items[] | select(.id == $id) | .id' file.json

Filter and transforrm

jq -r '{i: .id, t: .title}'
  • .[] returns each element of the array returned in the response.
  • [.org,.url] converts output to array
  • @tsv (newer version) tab separator
.[] | {org: .agency, topic: .topic, url: .endpoint.url} | select(.topic == "CourtCaseEvent") | [.org,.url] | @tsv
  • sort_by
sort_by(.topic) | .[] | {org: .agency, topic: .topic, url: .endpoint.url} | [.topic,.org,.url] | @csv

Without @csv using string interpolation ()

sort_by(.topic) | .[] | {org: .agency, topic: .topic, url: .endpoint.url} | "\(.topic)\t\(.org)\t\(.url)"

f

jq '.[] | {action: .category, id: .fileId, trackingId: .trackingId, time: .sentDateTime} | [.trackingId, .action, .category, .id, .time]  | @csv' file.json

dd

jq -r '.["dp:config"].SSLProxyProfile | .[] | .["@name"]' | less

Resource

jq-json faq

Passing arguments to spring-boot

mvn clean spring-boot:run -Drun.arguments="$@"

Install module mongos, also make any dependency, skip tests

./mvnw -am -pl mongos clean install -DskipTests

Test

./mvnw clean test

Init

  • Initialize the project npm init
  • Show versions or a project property. npm show @angular/cli versions
  • List packages npm list -g —depth=0

Install / Uninstall

Install the Express package locally and add it to dependencies section in package.son npm install express@4.0.0 --save npm install --save or npm install --save-dev or npm install --save-optional to update the package.json dependencies.

--save option instructs NPM to include the package inside of the dependencies section of your package.json. --save-dev and --save-optional save the package under devDependencies and optionalDependencies.

To make sure NPM doesn’t waste time installing devDependencies, use the --production option: npm install --production

Running scripts - 1 2

Look scripts in package.json start, actually defaults to node server.js, so that you do not specify nom run start | test

You can use the --prefix option to change working directory; directory must exist. npm install --prefix ./install/here You can use the --prefix option to change working directory; directory must exist. npm install --prefix ./install/here You can use the --prefix option to change working directory; directory must exist. npm install --prefix ./install/here Assuming this directory contains package.json with "build" command defined. npm --prefix /path/to/project run build

npm supports the "scripts" member of the package.json script, for the following scripts:

  • prepublish: Run BEFORE the package is published. (Also run on local npm install without any arguments.)
  • publish, postpublish: Run AFTER the package is published.
  • preinstall: Run BEFORE the package is installed
  • install, postinstall: Run AFTER the package is installed.
  • preuninstall, uninstall: Run BEFORE the package is uninstalled.
  • postuninstall: Run AFTER the package is uninstalled.
  • preupdate: Run BEFORE the package is updated with the update command.
  • update, postupdate: Run AFTER the package is updated with the update command.
  • pretest, test, posttest: Run by the npm test command.
  • prestop, stop, poststop: Run by the npm stop command.
  • prestart, start, poststart: Run by the npm start command.
  • prerestart, restart, postrestart: Run by the npm restart command. Note: npm restart will run the stop and start scripts if no restart script is provided. Additionally, arbitrary scripts can be run by doing npm run-script . node-gyp - Node.js native addon build tool

node-gyp is a cross-platform command-line tool written in Node.js for compiling native addon modules for Node.js. It bundles the gyp project used by the Chromium team and takes away the pain of dealing with the various differences in build platforms. It is the replacement to the node-wafprogram which is removed for node v0.8. If you have a native addon for node that still has awscript file, then you should definitely add a binding.gyp file to support the latest versions of node.

Multiple target versions of node are supported (i.e. 0.8, 0.9, 0.10, ..., 1.0, etc.), regardless of what version of node is actually installed on your system (node-gyp downloads the necessary development files for the target version).

  • brew

arch -x86_64 brew update brew update brew upgrade powershell --cask

  • OSX

pwsh hello.ps1

hidutil property --get "UserKeyMapping"

hidutil property --set '{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc":0x700000064,"HIDKeyboardModifierMappingDst":0x700000035}]}'

  • Catalina allow unidentified app to run

xattr -d com.apple.quarantine /Library/Java/JavaVirtualMachines/adoptopenjdk-13.0.1.jdk

Regex

 $a = "http://192.168.3.114:8080/compierews/" | Select-String -Pattern '^http://(.*):8080/(.*)/$'
 $a.Matches.Groups[1].Value

ExecutionPolicy

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

Using Initializer

https://start.spring.io/#!packageName=dhval.sitescope&name=sitescope

tmux shortcuts & cheatsheet

start new with session name or #:

tmux new -s myname

attach:

tmux attach -t name  #  (or at, or attach)
ctrl+b>d (ddeattach)

list sessions:

tmux ls

kill session:

tmux kill-session -t myname

Kill all the tmux sessions:

tmux ls | grep : | cut -d. -f1 | awk '{print substr($1, 0, length($1)-1)}' | xargs kill

In tmux, hit the prefix ctrl+b (my modified prefix is ctrl+a) and then:

Sessions

:new<CR>  new session
s  list sessions
$  name session

Windows (tabs)

c  create window
w  list windows
n  next window
p  previous window
f  find window
,  name window
&  kill window

Panes (splits)

%  vertical split
"  horizontal split

o  swap panes
q  show pane numbers
x  kill pane
[  scroll around
+  break pane into window (e.g. to select text by mouse to copy)
-  restore pane from window
⍽  space - toggle between layouts
q (Show pane numbers, when the numbers show up type the key to goto that pane)
{ (Move the current pane left)
} (Move the current pane right)
z toggle pane zoom

Sync Panes

You can do this by switching to the appropriate window, typing your Tmux prefix (commonly Ctrl-B or Ctrl-A) and then a colon to bring up a Tmux command line, and typing:

:setw synchronize-panes

You can optionally add on or off to specify which state you want; otherwise the option is simply toggled. This option is specific to one window, so it won’t change the way your other sessions or windows operate. When you’re done, toggle it off again by repeating the command. tip source

Resizing Panes

You can also resize panes if you don’t like the layout defaults. I personally rarely need to do this, though it’s handy to know how. Here is the basic syntax to resize panes:

PREFIX : resize-pane -D (Resizes the current pane down)
PREFIX : resize-pane -U (Resizes the current pane upward)
PREFIX : resize-pane -L (Resizes the current pane left)
PREFIX : resize-pane -R (Resizes the current pane right)
PREFIX : resize-pane -D 20 (Resizes the current pane down by 20 cells)
PREFIX : resize-pane -U 20 (Resizes the current pane upward by 20 cells)
PREFIX : resize-pane -L 20 (Resizes the current pane left by 20 cells)
PREFIX : resize-pane -R 20 (Resizes the current pane right by 20 cells)
PREFIX : resize-pane -t 2 20 (Resizes the pane with the id of 2 down by 20 cells)
PREFIX : resize-pane -t -L 20 (Resizes the pane with the id of 2 left by 20 cells)

Copy mode:

Pressing PREFIX [ places us in Copy mode. We can then use our movement keys to move our cursor around the screen. By default, the arrow keys work. we set our configuration file to use Vim keys for moving between windows and resizing panes so we wouldn’t have to take our hands off the home row. tmux has a vi mode for working with the buffer as well. To enable it, add this line to .tmux.conf:

setw -g mode-keys vi

With this option set, we can use h, j, k, and l to move around our buffer.

To get out of Copy mode, we just press the ENTER key. Moving around one character at a time isn’t very efficient. Since we enabled vi mode, we can also use some other visible shortcuts to move around the buffer.

For example, we can use "w" to jump to the next word and "b" to jump back one word. And we can use "f", followed by any character, to jump to that character on the same line, and "F" to jump backwards on the line.

   Function                vi             emacs
   Back to indentation     ^              M-m
   Clear selection         Escape         C-g
   Copy selection          Enter          M-w
   Cursor down             j              Down
   Cursor left             h              Left
   Cursor right            l              Right
   Cursor to bottom line   L
   Cursor to middle line   M              M-r
   Cursor to top line      H              M-R
   Cursor up               k              Up
   Delete entire line      d              C-u
   Delete to end of line   D              C-k
   End of line             $              C-e
   Goto line               :              g
   Half page down          C-d            M-Down
   Half page up            C-u            M-Up
   Next page               C-f            Page down
   Next word               w              M-f
   Paste buffer            p              C-y
   Previous page           C-b            Page up
   Previous word           b              M-b
   Quit mode               q              Escape
   Scroll down             C-Down or J    C-Down
   Scroll up               C-Up or K      C-Up
   Search again            n              n
   Search backward         ?              C-r
   Search forward          /              C-s
   Start of line           0              C-a
   Start selection         Space          C-Space
   Transpose chars                        C-t

Misc

d  detach
t  big clock
?  list shortcuts
:  prompt

Configurations Options:

# Mouse support - set to on if you want to use the mouse
* setw -g mode-mouse off
* set -g mouse-select-pane off
* set -g mouse-resize-pane off
* set -g mouse-select-window off

# Set the default terminal mode to 256color mode
set -g default-terminal "screen-256color"

# enable activity alerts
setw -g monitor-activity on
set -g visual-activity on

# Center the window list
set -g status-justify centre

# Maximize and restore a pane
unbind Up bind Up new-window -d -n tmp \; swap-pane -s tmp.1 \; select-window -t tmp
unbind Down
bind Down last-window \; swap-pane -s tmp.1 \; kill-window -t tmp

Resources:

  • -c Copy Node, as XML
  • -v Print Node
  • -n Read File
  • -N Specify Namespace
  • format --indent-tab prettify

Find all values in files.

find . -type f -exec xmlstarlet sel -N ns="http://jnet.state.pa.us/message/jnet/EventMessageConsumer/1" -T -t -m "//ns:NotifyStatusCode" -v "text()" -n "{}" \;

find . -type f -exec xmlstarlet sel -T -t -m "//*[local-name()='CourtCaseEvent']"  -o "WantEntryAccept for AOPC_WARRANT_ID=" -v "//*[local-name()='ActivityID']/*[local-name()='ID']/text()"  -o " NIC=" -v "//*[local-name()='DocumentFileControlID']/*[local-name()='ID']/text()" -n "{}" \;

Print first node in side “Message” node

sel -t -m "//*[local-name()='project']" -o "\""  -v "." -o "\"" -n file.xml

Print attribute

xml sel -N xsd="http://www.w3.org/2001/XMLSchema" -T -t -m '//xsd:import' -v '@schemaLocation' -n xsd.xsd

Print imported namespace, use bash and export -f get_xpath (Functions cannot be exported in ZSH)

xmlstarlet sel -N xsd="http://www.w3.org/2001/XMLSchema" -T -t -m "//xsd:enumeration" -o ", 'or text()=', apos, '" -v "@value" -o "', apos" -n ~/Desktop/sample.xml

Extract Schema from WSDL

xmlstarlet sel -N xsd="http://www.w3.org/2001/XMLSchema" -T -t -m "//xsd:schema" -v "@targetNamespace"  -n ElectronicReporting-Full.wsdl
xmlstarlet sel -N xsd="http://www.w3.org/2001/XMLSchema" -t -m "//xsd:schema[@targetNamespace='http://www.jnet.state.pa.us/niem/jnet/CountyInmateEvent/1']" -c .  -n File.wsdl

Print all child[@name] under configuration element

sel -T -t -m "//*[local-name()='configuration']/*" -v "name()" -o "@"  -v "@name" -n file.xml 

Update Text

xmlstarlet edit -L --update "//*[local-name()='Text']" --value 'FAIL' file.xml

Delete Attribute, ed=subcommand, d=delete:

xmlstarlet ed -d '//@read-only' input.xml
xmlstarlet ed --inplace  -d "//*[local-name()='configuration']/HTTPSourceProtocolHandler[@name='aopc_http-fsh']" file.xml
xmlstarlet ed --inplace  -d "//*[local-name()='Header']" file.xml

xmllint

Pretty all XML files in folder.

find . -name "*.xml" -type f -exec xmllint --output '{}' --format '{}' \;
  • --output FILE

Canonical XML - Similar to identity transform; use —format for indentation

xmllint --c14n file.xml 

Validate against XSD

xmllint --schema file.xsd --noout file.xml 

XML Minify

xmllint --noblanks file.xml 

saxon

Transform using Saxon

saxon -xsl:parse.xslt input.xml

XPATH

  • Match using local name

//*[local-name() = 'Element' and namespace-uri() = 'namespace']

  • Select item with @Type="CARMENT" and ID is not-empty

//*[@Type="CARMENT"]/@ID[not(.="")]

Find a local node having certain text or attribute

//*[local-name()='a'][*[local-name()='aCode']='aaa']
//*[local-name()='NoticeText']/@*[local-name()='ownerProducer']

Check if node contains certain text after a text prefix

/*/*[local-name()='ActivityCategoryText'][contains('Admission', substring-after(., 'Inmate '))]

/*/*[local-name()='ActivityCategoryText'][contains('Maintenance Message|Admission|Permanent Release', substring-after(., 'Inmate '))]

Node text start-with.

//*[local-name()='UserDefinedTrackingID'][starts-with(., '7iQG')]
string(//*[local-name()='Body']/*/*/*[local-name()='Supervision']/*[local-name()='SupervisionAugmentation']/*[local-name()='SupervisionReportingCountyPACode'
 or local-name()='SupervisionReportingCountyName'][last()])

Multiple or conditions so

    <xsl:if test="$var='ab' or $var='bc' or $var='ca' ">
    <xsl:if test="contains('|ab|bc|ca|', concat('|', $var, '|'))">

Using not operator in test condition

not(A = "NA") ==> true if A is absent or not equal to "NA"

A != "NA" ==> returns true if A is present and not equal to "NA"

Getting one of the child node: last() , [1], last() - 1

(//element[@name='D'])[last()]

First hr having 'edge' class.

//hr[@class="edge" and position()=1]

Table with one row and two columns //table[count(tr)=1 and count(tr/td)=2]

Nodes having three children. //*[count(*)=3]

Last row of table ./table/tr[last()]

All divs that have form

//div/form/parent::*

//table[parent::div[@class="pad"] and not(@id)]//a // any anchor in a table without id, contained in a div of "pad" class

/html/body/div/*[preceding-sibling::h4] // give me whatever after h4 //tr/td[font[@class="head" and text()="TRACK"]] // all td that has font of a "head" class and text "TRACK"

FInd element

(//E)[2] // second //*[.="t"] // element containing text t exactly //E[contains(text(), "t")] // element containing text t (css: E:contains(t))

//E1[@id=I1] | //E2[@id=I2] // element or //E1[@id=I1 or @id=I2] // element with attribute id I1 or id I2

Find elements with attributes.

//E[@A]
//E/@A // select attribute A of element //E[@A="t"]
//E[contains(@A,"t")] // attribute A containing text t //E[starts-with(@A, "t")]
//E[ends-with(@A, "t")]
//E[contains(concat(" ", @A, " "), " w ") // attribute A containing word w //E[matches(@A, "r")]
//*[not(@disabled)] // any element not having disabled attribute //*[@id="TestTable"]//tr[3]//td[2] // css: #TestTable tr:nth-child(3) td:nth-child(2)

//E/*[1] // css: E > *:first-child //E[1] // css: E:first-of-type //E/*[last()] // css: E *:last-child //E[last()] // css: E:last-of-type //E[2] // css: E:nth-of-type(2)

//*[2][name()="E"] // second child that is an element (css: E:nth-child(2)) //E[last()-1] // second-to-last child (css: E:nth-last-of-type(2)) //*[last()-1][name()="E"] // second-to-last child that is an element (css: E:nth-last-child(2)) //E1/[E2 and not( *[not(self::E2)])] // element with only children //E/.. // parent of element //*[@id="I"]/.../.../.../E // descendant of element with id I using specific path (css: #I > … > … > … > E) //*[@id="I"]//E // descendant of element with id I using unspecified path (css: #I E) //E[count(*)=0] // element with no children (E:empty) //E[count(*)=1] // element with an only child //E[count(preceding-sibling::*)+count(following-sibling::*)=0] // element that is an only child (css: E:only-child) //E[count(../E) = 1] // element with no siblings (css: E:only-of-type)

XPath Functions

boolean(), string(), number(), true(), false(), not(expression)  

name([node-set]), namespace-uri([node-set])  

count(node-set), last(), position()

contains(haystack-string, needle-string)
concat(string1, string2 [stringn]*)  
normalize-space(string)               
starts-with(haystack, needle)
string-length([string])
substring(string, start [length]) 
substring-after(haystack, needle) 
substring-before(haystack, needle)
translate(string, abc, XYZ)               

XPath Axes

An axis represents a relationship to the context (current) node, and is used to locate nodes relative to that node on the tree.

self(.), parent(..) ancestor, ancestor-or-self, descendant, descendant-or-self, following, following-sibling, preceding, preceding-sibling

Finding Axes

//E2/following-sibling::E1 // element following some sibling (css: E2 ~ E1) //E2/following-sibling::*[1][name()="E1"] // element immediately following sibling (css: E2 + E1) //E2/following-sibling::*[2][name()="E1"] // element following sibling with one intermediary (css: E2 + * + E1) //E/following-sibling::* // sibling element immediately following (css: E + *) //E2/preceding-sibling::E1 // element preceding some sibling //E2/preceding-sibling::*[1][name()="E1"] // element immediately preceding sibling //E2/preceding-sibling::*[2][name()="E1"] // element preceding sibling with one intermediary //E/preceding-sibling::*[1] // sibling element immediately preceding

  • Use exclude-result-prefixes attribute of the xsl:stylesheet element to suppress namespaces from the output document. extension-element-prefix specifies XSLT extension functions.
<xsl:stylesheet version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
         xmlns:Namespace="http://www.something.com"
         exclude-result-prefixes="ns1 ns2">

</xsl:stylesheet>
  • To use EXSLT functions like the one in the namespace http://exslt.org/common you don't need the extension-element-prefix attribute. That is only need if you want to use extension elements like func:function in the namespace http://exslt.org/functions. The extension-element-prefix attribute simply signals that any elements with that prefix are not literals result elements but rather extension instructions in addition to those instructions defined by the XSLT language.

There is no problem storing a node-set in a variable in XSLT 1.0, and no extensions are needed. If you just use an XPath expression in select attribute of xsl:variable, you'll end up doing just that. The problem is only when you want to store the nodes that you yourself had generated in a variable, and even then only if you want to query over them later. The problem here is that nodes you output don't have type "node-set" - instead, they're what is called a "result tree fragment". You can store that to a variable, and you can use that variable to insert the fragment into output (or another variable) later on, but you cannot use XPath to query over it. That's when you need either EXSLT node-set() function (which converts a result tree fragment to a node-set), or XSLT 2.0 (in which there are no result tree fragments, only sequences of nodes, regardless of where they come from).

  • Readable XPATH

The key revelation that neophyte XSLT programmers miss, making there one-liner XPATH hard to read. You are allowed to have line separators inside your attribute values, including @select. And XPath understands this, happily accepting multi-line selects!

<xsl:value-of select="concat('cert:',
    dp:cert-from-issuer-serial($Signature/*[local-name()='KeyInfo']
    /*[local-name()='SecurityTokenReference']
    /*[local-name()='X509Data']
    /*[local-name()='X509IssuerSerial']
    /*[local-name()='X509IssuerName'],
    $Signature/*[local-name()='KeyInfo']
    /*[local-name()='SecurityTokenReference']
    /*[local-name()='X509Data']
    /*[local-name()='X509IssuerSerial']
    /*[local-name()='X509SerialNumber']))"/>
  • White Spaces, There are several nodes that are not visble to you. A test of "xyzzy/state = 'New Jersey'" doesn’t match:
<xsl:template match="xyzzy">
    <xyzzy>
        <state>
            New Jersey
        </state>
    </xyzzy>
</xsl:template>
  • Copy nodes without namespace SO

If you were able to use XSLT 2.0 then you could try setting copy-namespaces="no" on the copy-of but that isn't an option in XSLT 1.0. So instead of using copy-of you need to use templates to copy that node (and all its descendants recursively) without including the namespace nodes.

<xsl:template match="*" mode="copy">
  <xsl:element name="{name()}" namespace="{namespace-uri()}">
    <xsl:apply-templates select="@*|node()" mode="copy" />
  </xsl:element>
</xsl:template>

<xsl:template match="@*|text()|comment()" mode="copy">
  <xsl:copy/>
</xsl:template>

Creating an element

<xsl:variable name="request">  
   <xsl:element name="{text()}">  
      <xsl:copy-of select="$ctxData" />  
   </xsl:element>  
</xsl:variable>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment