22 * Provides classes and predicates for working with XML files and their content.
33 */
44
5- import semmle.code.cpp.Location
5+ import semmle.files.FileSystem
66
77/** An XML element that has a location. */
88abstract class XMLLocatable extends @xmllocatable {
99 /** Gets the source location for this element. */
1010 Location getLocation ( ) { xmllocations ( this , result ) }
1111
1212 /**
13- * Holds if this element has the specified location information,
14- * including file path, start line, start column, end line and end column.
13+ * Holds if this element is at the specified location.
14+ * The location spans column `startcolumn` of line `startline` to
15+ * column `endcolumn` of line `endline` in file `filepath`.
16+ * For more information, see
17+ * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
1518 */
1619 predicate hasLocationInfo (
1720 string filepath , int startline , int startcolumn , int endline , int endcolumn
1821 ) {
1922 exists ( File f , Location l | l = this .getLocation ( ) |
20- locations_default ( l , unresolveElement ( f ) , startline , startcolumn , endline , endcolumn ) and
23+ locations_default ( l , f , startline , startcolumn , endline , endcolumn ) and
2124 filepath = f .getAbsolutePath ( )
2225 )
2326 }
2427
25- /** Gets a printable representation of this element. */
28+ /** Gets a textual representation of this element. */
2629 abstract string toString ( ) ;
2730}
2831
@@ -31,6 +34,12 @@ abstract class XMLLocatable extends @xmllocatable {
3134 * both of which can contain other elements.
3235 */
3336class XMLParent extends @xmlparent {
37+ XMLParent ( ) {
38+ // explicitly restrict `this` to be either an `XMLElement` or an `XMLFile`;
39+ // the type `@xmlparent` currently also includes non-XML files
40+ this instanceof @xmlelement or xmlEncoding ( this , _)
41+ }
42+
3443 /**
3544 * Gets a printable representation of this XML parent.
3645 * (Intended to be overridden in subclasses.)
@@ -106,15 +115,21 @@ class XMLFile extends XMLParent, File {
106115 override string toString ( ) { result = XMLParent .super .toString ( ) }
107116
108117 /** Gets the name of this XML file. */
109- override string getName ( ) { files ( this , result , _ , _ , _ ) }
118+ override string getName ( ) { result = File . super . getAbsolutePath ( ) }
110119
111- /** Gets the path of this XML file. */
112- string getPath ( ) { files ( this , _, result , _, _) }
120+ /**
121+ * DEPRECATED: Use `getAbsolutePath()` instead.
122+ *
123+ * Gets the path of this XML file.
124+ */
125+ deprecated string getPath ( ) { result = getAbsolutePath ( ) }
113126
114- /** Gets the path of the folder that contains this XML file. */
115- string getFolder ( ) {
116- result = this .getPath ( ) .substring ( 0 , this .getPath ( ) .length ( ) - this .getName ( ) .length ( ) )
117- }
127+ /**
128+ * DEPRECATED: Use `getParentContainer().getAbsolutePath()` instead.
129+ *
130+ * Gets the path of the folder that contains this XML file.
131+ */
132+ deprecated string getFolder ( ) { result = getParentContainer ( ) .getAbsolutePath ( ) }
118133
119134 /** Gets the encoding of this XML file. */
120135 string getEncoding ( ) { xmlEncoding ( this , result ) }
@@ -129,7 +144,17 @@ class XMLFile extends XMLParent, File {
129144 XMLDTD getADTD ( ) { xmlDTDs ( result , _, _, _, this ) }
130145}
131146
132- /** A "Document Type Definition" of an XML file. */
147+ /**
148+ * An XML document type definition (DTD).
149+ *
150+ * Example:
151+ *
152+ * ```
153+ * <!ELEMENT person (firstName, lastName?)>
154+ * <!ELEMENT firstName (#PCDATA)>
155+ * <!ELEMENT lastName (#PCDATA)>
156+ * ```
157+ */
133158class XMLDTD extends @xmldtd {
134159 /** Gets the name of the root element of this DTD. */
135160 string getRoot ( ) { xmlDTDs ( this , result , _, _, _) }
@@ -156,7 +181,17 @@ class XMLDTD extends @xmldtd {
156181 }
157182}
158183
159- /** An XML tag in an XML file. */
184+ /**
185+ * An XML element in an XML file.
186+ *
187+ * Example:
188+ *
189+ * ```
190+ * <manifest xmlns:android="http://schemas.android.com/apk/res/android"
191+ * package="com.example.exampleapp" android:versionCode="1">
192+ * </manifest>
193+ * ```
194+ */
160195class XMLElement extends @xmlelement, XMLParent , XMLLocatable {
161196 /** Holds if this XML element has the given `name`. */
162197 predicate hasName ( string name ) { name = getName ( ) }
@@ -201,7 +236,16 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
201236 override string toString ( ) { result = XMLParent .super .toString ( ) }
202237}
203238
204- /** An attribute that occurs inside an XML element. */
239+ /**
240+ * An attribute that occurs inside an XML element.
241+ *
242+ * Examples:
243+ *
244+ * ```
245+ * package="com.example.exampleapp"
246+ * android:versionCode="1"
247+ * ```
248+ */
205249class XMLAttribute extends @xmlattribute, XMLLocatable {
206250 /** Gets the name of this attribute. */
207251 string getName ( ) { xmlAttrs ( this , _, result , _, _, _) }
@@ -222,7 +266,15 @@ class XMLAttribute extends @xmlattribute, XMLLocatable {
222266 override string toString ( ) { result = this .getName ( ) + "=" + this .getValue ( ) }
223267}
224268
225- /** A namespace used in an XML file */
269+ /**
270+ * A namespace used in an XML file.
271+ *
272+ * Example:
273+ *
274+ * ```
275+ * xmlns:android="http://schemas.android.com/apk/res/android"
276+ * ```
277+ */
226278class XMLNamespace extends @xmlnamespace {
227279 /** Gets the prefix of this namespace. */
228280 string getPrefix ( ) { xmlNs ( this , result , _, _) }
@@ -241,7 +293,15 @@ class XMLNamespace extends @xmlnamespace {
241293 }
242294}
243295
244- /** A comment of the form `<!-- ... -->` is an XML comment. */
296+ /**
297+ * A comment in an XML file.
298+ *
299+ * Example:
300+ *
301+ * ```
302+ * <!-- This is a comment. -->
303+ * ```
304+ */
245305class XMLComment extends @xmlcomment, XMLLocatable {
246306 /** Gets the text content of this XML comment. */
247307 string getText ( ) { xmlComments ( this , result , _, _) }
@@ -256,6 +316,12 @@ class XMLComment extends @xmlcomment, XMLLocatable {
256316/**
257317 * A sequence of characters that occurs between opening and
258318 * closing tags of an XML element, excluding other elements.
319+ *
320+ * Example:
321+ *
322+ * ```
323+ * <content>This is a sequence of characters.</content>
324+ * ```
259325 */
260326class XMLCharacters extends @xmlcharacters, XMLLocatable {
261327 /** Gets the content of this character sequence. */
0 commit comments