-
-
Save dhval/49aedf8aee5412c7cd906e96a6d8f601 to your computer and use it in GitHub Desktop.
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 tool install --global dotnet-warp --version 1.1.0
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
Install or Upgrade a package
choco install microsoft-windows-terminal
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
- PS Azure Get Started
- Power Shell Integrated Scripting Env
- PS6 -Package Mgmt
- Reddit - cant_install_any_powershell_modules
- Repository Setup
- webapp list
- appservice plan list
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
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 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"
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
- 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
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
--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
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
...
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.
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](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.
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
- 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
Git scm documentation Apply Patch Interative Merge
- Git delete all branches except master git branch | grep -v "master" | xargs git branch -D
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 |
- 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 |
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 |
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
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 [email protected] --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).
- Easy to use, consistent interface
- Same commands to build your module on every platform
- Supports multiple target versions of Node http://blog.timsommer.be/npm-and-the-package-json-file/
- brew
arch -x86_64 brew update brew update brew upgrade powershell --cask
- OSX
pwsh hello.ps1
- Remapping keys https://apple.stackexchange.com/questions/304191/remap-the-%C2%B1-key-on-my-magic-keyboard
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
When want to group and not capture them, since we are using or operator here.
(?:jxdm|niem)
Using Initializer
https://start.spring.io/#!packageName=dhval.sitescope&name=sitescope
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
tmux kill-session -t myname
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:
:new<CR> new session
s list sessions
$ name session
c create window
w list windows
n next window
p previous window
f find window
, name window
& kill window
% 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
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
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)
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
d detach
t big clock
? list shortcuts
: prompt
# 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
-c
Copy Node, as XML-v
Print Node-n
Read File-N
Specify Namespaceformat --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
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
Transform using Saxon
saxon -xsl:parse.xslt input.xml
- 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)
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)
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 likefunc: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>
<xsl:variable name="request">
<xsl:element name="{text()}">
<xsl:copy-of select="$ctxData" />
</xsl:element>
</xsl:variable>