# XN XML Needle (XN) is a simple tool for injecting faults into XML documents. ## Description The purpose of the tool is to hide a metaphorical "needle in a haystack" in large XML files, such as an EtherCAT SubDevice Information or ESI file. Therefore it is a FIT (fault injection test) tool, but can be used for general purpose manipulation. XPath is utilized to specify precise locations combined with a good enough set of instructions to do CRUD operations. As the main application lies with injecting faults into ESI files, additional functions for calculating checksums are included. This allows recalculation of CRC32 secured sections of a given document, such as modules in an ESI file. ## Language Specification The XNeedle language consists of three distinct parts. 1. Expressions Expressions may consist of function calls, arithmetic operations, sting concats and values. This example prepends the existing inner text of a given node with "Faulty '", and appends the evaluated string "': 2+2=10". ``` text("Faulty '" .. text() .. "': " .. string(1+1**2) .. "+2=10"); ``` 2. Rules A rule consists of a selector and a block. The selector is using XPath to select any amount of nodes, for which the block is applied to. A block however can consist of multiple expressions, nested rules or bangs. This example sets the text and an attribute based on their respective selectors. ``` $("//Device/Type[@ProductCode='#x0B583052' and @RevisionNo='#x00110000']/..") { $("Type") { attr("ProductCode", hex(0xDEADBEEF)); } $("Name[@LcId='1033']") { cdata("LE2904, 4 Ch. Danger Output 24V, 0.5A, TwinUNSAFE"); }; } ``` 3. Bangs Bangs are special function calls which take either a string or XPath as parameters, and make addition changes to the document. They are prefixed with, as the name implies, an exclamation mark. This example adds, removes and swaps nodes. ``` $("RxPdo/Index[.="#x1600"]/..") { # Modify name $(Name) { text("FSoE Outputs"); } # Select the Entry/Index #x7000 and change it to #x9001 $(Entry/Index[.="#x7000"]) { text("#x9001"); } # Select the Entry with Index #x7001 and SubIndex 4, remove it $(Entry/Index[.="#x7001"]/../SubIndex[.="4"]/..) { remove(); } # Select the 3rd Entry $(Entry[3]) { # Add a tag before the above selection !before("Entry") { # Add these tags with their contents respectively !add("Index") { text("#x4711"); }; !add("SubIndex") { text("3"); } !add("BitLen") { text("256"); } !add("Name") { text("Garbage"); } !add("DataType") { text("UINT"); } } } # Swap Entries swap("Entry[3]", "Entry[4]"); } ``` 4. Comments Comments are prefixed with the '#' character. ## Running the command ```bash xn sample.xn -i input.xml -o output.xml ``` The file `sample.xn` is the transformation specification as outlined above. For input and output, see `input.xml` and `output.xml` respectively. Refer to the help text using the `--help` switch for more details.