<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Publishing DTD v1.1d1 20130915//EN" "JATS-journalpublishing1.dtd"[]>
<article dtd-version="1.1d1" article-type="review-article" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xml:lang="en">
<front>
<?covid19?>
I need to find if the <?covid19?> processing instruction is present in the XML or not.
Pseudo-code in jQuery:
$("<?covid19?>").length
While there are no CSS selectors to select processing instructions like elements, there are two nice APIs which you can use to avoid iterating over the DOM tree manually.
Let’s say your XML document is the
XMLDocumenttheDocument; you can create one by parsing the XML string with theDOMParserAPI:NodeIteratorAPIFinding all processing instructions is possible using the
NodeIteratorAPI (usingtheDocument.createNodeIterator).iteratorAllis aNodeIteratorwhich shows all processing instructions.iteratorCOVID19is aNodeIteratorwhich shows all processing instructions with the namecovid19.The
TreeWalkerAPI (usingtheDocument.createTreeWalker) is very similar to theNodeIteratorAPI.XPath Iterator API
Finding all processing instructions is also possible using XPath (using
theDocument.evaluate). The results areXPathResults.Explanation of the XPath syntax:
//processing-instruction()processing-instruction('covid19')covid19The
XPathResult.ORDERED_NODE_ITERATOR_TYPEis useful to ensure that the nodes get returned in document-order.xPathAllis anXPathResultiterator which shows all processing instructions.xPathCOVID19is anXPathResultiterator which shows all processing instructions with the namecovid19.Iteration helper
The two APIs are great in terms of browser support, but that means they’re old enough that they don’t have a modern iteration protocol. But this is where a generator proves useful.
This code defines the generator function
consumeDOMIteratorwhich will just fully consume all nodes found by either iterator. Since theNodeIteratorAPI’s method to get the next result is callednextNode, and the XPath method is callediterateNext, this function checks which of these method names to use. If it can’t find the appropriate method, it’ll defer to the default iteration protocol. Then, a simplewhileloop repeatedly calls one of these methods andyields them untilnullis returned.Now the function can be used to create an Array from the iterator.
Array.fromcan be used to achieve this easily:To check the existence of a processing instruction, simply check the Array’s
lengthor ifiteratorCOVID19.nextNode()orxPathCOVID19.iterateNext()return aNode.Note that its name includes
consumefor a reason: once you start iterating over the API results using this function to create an Array, the state of the results changes. Once you reach the end, either iterator will be at the “end” of the document, so there is no next node. While theNodeIteratorAPI has apreviousNode, the XPath Iterator API does not have a corresponding method; in general iterators can only be iterated once.XPath Snapshot API
Alternatively,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPEmay be used to get a more direct set of results that can be iterated over more easily.Now, since the
XPathResultis a snapshot, thesnapshotLengthcan be used in order to get all thesnapshotItems. Again,Array.fromcan be used to achieve this easily:The only difference to the iterator approach is that the
XPathResultdoes not change when the underlying document is mutated.To check the existence of a processing instruction, simply check the Array’s
lengthor ifsnapshotCOVID19.snapshotItem(0)returns aNode.Full code
This code snippet demonstrates in full how to get all processing instructions of the form
<?covid19?>and, for example, get theirnodeValue: