Define Tags

This topic explains how to write the statements in a JUNOS Output Definition Language (ODL) file that generate definitions for tags in the XML document type definition (DTD) file for your JUNOS module.

It discusses the following topics:

Decide How to Tag Output

The best basis for the set of JUNOScript tags that describe a JUNOS module’s output is usually the formatted ASCII output that the JUNOS module currently generates in response to command-line interface (CLI) commands such as show. The C data structures in which the module collects and stores output are also a good basis for tags. The following are general principles for creating tags:

About tag Statements

The tag statement is the basic building block of the ODL file. The tag statement defines the tag name and all other information required for your module to emit the tag successfully. When you compile the ODL file, the ODL compiler transforms and records the information in several files. Specifically, the compiler generates an !ELEMENT statement in the DTD and entries in JUNOScript library and include files that your JUNOS module then uses to emit tagged output. For examples of the DTD statements that result from ODL statements, see Summary of ODL and Resulting DTD Statements. For a discussion of the library and include files, see Write and Compile the ODL File.

Character Set for Tag Names

JUNOScript tag names can contain any number of the following characters. The ODL compiler exits with an error if a tag name includes other characters. By convention, JUNOScript tag names use full English words rather than abbreviations or acronyms. For more guidance about tag names, see Decide How to Tag Output.

By JUNOScript convention, a tag name can also contain up to one colon ( : ). The string to the left of the colon identifies the XML namespace to which the tag belongs, and the string to the right is the tag name. For example, the <junos:error> tag belongs to the generic JUNOScript namespace defined in the junos.dtd file. Use tag names of this form only when referring to a tag defined in another DTD, however. Do not include a colon in tag names you define in your ODL file, even if the opening string accurately designates the namespace.

Classes of Tags

There are two classes of JUNOScript tags:

Note:
In the tag for a tag that has the same name as an ODL statement, you must enclose the name in quotation marks (" ") to prevent the ODL compiler from interpreting the name as a statement. The following example creates a tag called description, which is also the name of an ODL statement.

tag "description" {
	type string;
}

For a list of all ODL statement names, see Summary of ODL and Resulting DTD Statements and Summary of Formatting Statements.

Create Simple tag Statements

A simple tag contains a character string or numerical value. The tag statement for a simple tag uses the following syntax to define the tag’s name and type. White space is not significant in an ODL file, so spreading the statement over multiple lines as shown makes it easier to read.

tag tag-name {
	type type;
}

The tag-name must follow the rules listed in About tag Statements. The type statement defines the type of information marked by the tag, using one of the strings described in JUNOScript Types.

The type statement has an advisory effect only, in two senses:

Despite its advisory nature, you must include the type statement on the first tag statement for a tag in the ODL file. If there are subsequent statements for the same tag (presumably to define it as the child of one or more other container tags), you do not need to repeat the type statement, and cannot change the tag’s type to a different value. The syntax for subsequent instances of a tag statement is as follows:

tag tag-name;

Although you cannot repeat the type statement, you can put statements of other kinds on subsequent tag statements for a tag. The additional statements apply to all instances of the tag in the ODL file, including the original statement. To minimize confusion, it is best to include all statements on the original statement only. For information about the other kinds of statements, see Assign XML Attributes to a Tag and Specify Other Tag Properties.

JUNOScript Types

The type statement indicates the kind of information contained in a simple tag. The following sections discuss the JUNOScript type statements in decreasing order of occurrence in most JUNOS output.

string Type

The string type indicates that the tag contains a string of ASCII text. The following example creates a tag called <username>:

tag username {
	type string;
}

The tag can be used to report a person’s name, as in the following:

<username>Frank Booth</username>

int Type

The int type indicates that the tag contains an integer value, which can be signed. The following example creates a tag called <input-bytes>:

tag input-bytes {
	type int;
}

It can be used to report the number of bytes of data an interface has received, in this case 94,043.

<input-bytes>94043</input-bytes>

Because type statements are advisory only, the JUNOS module emits the value 94043 as a string (the type of data that XML calls parsed character data). A JUNOScript client must convert it to an actual integer before performing mathematical operations on it.

enum Type

The enum type indicates that the tag contains one of a defined set of values. It takes a subtype argument, for which acceptable values are string and int. Each enclosed choice statement defines one possible value. When subtype is string, you must enclose each possible value in quotation marks (" ") as shown in the following syntax statement. The quotation marks indicate that the name of each choice is a single token. Quotation marks are required only when the string contains one or more spaces, but by convention they are always used when the choice name is a character string.

The enum type statement also includes a define statement for each choice. The DEFINITION_STRING specifies the name of the #define statement that the ODL compiler generates for the choice and records in the module_odl.h file associated with your JUNOS module. For more information about the ODL compiler’s output, see Syntax of the odc Command.

tag tag-name {
	type enum subtype {
		choice "choice-name" {
			define DEFINITION_STRING;
		}
	}
}

Example: enum string Type

The following example illustrates the use of the enum string type. It defines three possible content values for the <administrative-status> tag—up, down, and test—and the corresponding #define names—IFX_ADMIN_STATUS_UP, IFX_ADMIN_STATUS_DOWN, and IFX_ADMIN_STATUS_TEST.

tag administrative-status {
	type enum string {
		choice "up" {
			define IFX_ADMIN_STATUS_UP;
		}
		choice "down" {
			define IFX_ADMIN_STATUS_DOWN;
		}
		choice "test" {
			define IFX_ADMIN_STATUS_TEST;
		}
	}
}

In the following example, the tag contains the value test:

<administrative-status>test</administrative-status>

Example: enum int Type

The following example illustrates the use of the enum int type. It defines two possible values for the <length> tag—1 and 2—and the corresponding preprocessor values—ONE and TWO.

tag length {
	type enum int {
		choice 1 {
			define ONE;
		}
		choice 2 {
			define TWO;
		}
	}
}

In the following usage example, the tag contains the value 1:

<length>1</length>

empty Type

The empty type indicates that the tag has no contents. You can use an empty tag to represent status indicators such as a router interface’s device, link, family, or address flags. For a discussion of this usage, see Format Lists of Status Indicators.

The following example creates an empty tag called <snmp-trap-flag/>.

tag snmp-trap-flag {
	type empty;
}

The resulting tag follows. It demonstrates the conventional notation for an empty XML tag—a single tag with a slash after the name, rather than a set of opening and closing tags with nothing between them.

<snmp-trap-flag/>

You can also use the presence or absence of an empty tag to represent a boolean value. The alternative is to use a string or enum string type, recording the appropriate boolean value as the tag’s contents.

ipaddr Type

The ipaddr type indicates that the tag contains an IP address, or an address and prefix, in dotted decimal format. The following example creates a tag called <router-id>:

tag router-id {
	type ipaddr;
}

The tag can be used to report a router interface’s IP address:

<router-id>192.168.0.254</router-id>

macaddr Type

The macaddr type indicates that the tag contains a 48-bit media access control (MAC) address encoded as a series of six hexadecimal values separated by colons. The following example creates a tag called <mac-address>:

tag mac-address {
	type macaddr;
}

The tag can be used to report a router interface’s MAC address:

<mac-address>01:02:03:04:05:06</mac-address>

uint64 Type

The uint64 type indicates that the tag contains a 64-bit integer value that is unsigned. As a 64 bit integer, the value of any tag using this type can range from 0 to 18446744073709551615 ((2^64) – 1). The following example creates a tag called pfe-input-packet:

tag pfe-input-packets {
  type uint64;
}

The tag can be used to handle the Packet Forwarding Engine’s input packets.

<pfe-input-packets>5000000000</pfe-input-packets>

Create Container tag Statements

A container tag contains other tags, and its tag statement lists the other tags that can or must occur within it. The following specifies the syntax for the simplest kind of container tag, one that contains only one simple tag:

tag container-tag-name {
	tag child-tag-name {
		type type;
	}
}

The container-tag-name and child-tag-name names must obey the rules listed in About tag Statements About tag Statements. The tag statement for each simple tag must include a type statement, just as for simple tag statements not contained in a container tag.

You can nest container tag statements to any depth. The following example illustrates four levels of nesting: <rpc-reply> contains <environment-information>, which contains <environment-record>, which contains the simple tag <status>.

tag rpc-reply{
	tag environment-information {
		tag environment-record {
			tag status {
				type string;
			}
		}
	}
}

You cannot define the type for a container tag as you do for a simple tag, because JUNOScript does not permit container tags to contain the kinds of data elements to which type statements apply. In imposing this restriction, JUNOScript is stricter than XML, which allows mixing of data values and child tags in a container tag.

A common error that ODL users make is to flatten the hierarchy and repeat the same group of like tags at the same hierarchy level, implying the hierarchy by using a common prefix for tag names. Doing this causes some of the advantages of XML to be lost. The following pseudocode represents this behavior:

Pseudocode of a Flattened Hierarchy (Not Recommended):

dfc-statistics-information
	input-packets-control-protocol
	input-packets-control-protocol-iri
	input-packets-control-protocol-drop-not-ip
	input-packets-control-protocol-drop-not-udp
	input-packets-control-protocol-drop-invalid-dest-ip
	input-packets-control-protocol-drop-no-memory
	input-packets-control-protocol-drop-unauthorized
	input-packets-control-protocol-drop-bad-req
	input-packets-control-protocol-drop-unknown-control-source
	input-packets-control-protocol-drop-not-dtcp
	input-packets-control-protocol-drop-bad-cmdline
	input-packets-control-protocol-drop-other
	output-packets-control-protocol-total-sent
	output-packets-drop-control-protocol
	input-packets-cap-data
	input-packets-drop-cap-data-not-ipv4
	input-packets-drop-cap-data-too-small
	input-packets-drop-cap-data-drop
	input-packets-drop-cap-data-nomatch
	input-packets-drop-unknown
	output-packets-cap-data
	output-packets-drop-cap-data

When possible, create hierarchical XML tags. The benefit of hierarchical XML is that the consumer of the XML, whether the consumer is a script or a human, can parse the XML based on the hierarchy, and skip the portion of the XML that is not of interest. Rather than parsing the entire XML document, the consumer can read only the part of the XML that is of interest. The following pseudocode represents this behavior:

Pseudocode of an Actual Hierarchy (Recommended):

dfc-statistics-information
	control-packets
		received
			total-received
			iri
			dropped
				not-ip
				not-udp
				invalid-dest-ip
				no-memory
				unauthorized
				bad-request
				unknown-control-source
				not-dtcp
				bad-cmdline
				other
		sent
			total-sent
			total-captured
			total-dropped
	captured-packets
		received
			total-received
			dropped
				not-ipv4
				too-small
				data
				data-nomatch
				unknown
		sent
			total-sent
			total-dropped

If the tags are nested as shown in this example, a script writer interested in getting the statistics for all captured packets sent can parse the following XML hierarchy:

dfc-statistics-information
	captured-packets
		sent

Assign XML Attributes to a Tag

An XML attribute is a statement that provides auxiliary information about a tag. It appears along with the tag name within the angle brackets that delimit an opening or empty tag element. Attributes are always optional for JUNOScript tags but are useful for specifying header text strings or formatting information to be used when displaying the content of the tag. Do not use attributes to record or convey information that a client application needs for a complete understanding of the output. Instead, use an actual tag to contain such information.

To define an XML attribute, include the attribute statement in the tag statement. JUNOScript attributes have a type, just as simple tags do, so the attribute statement must include a type statement of the kind described in JUNOScript Types JUNOScript Types. Both simple and container tags can have attributes, as shown in the following syntax statement:

tag simple-tag-name {
	attribute attribute-name {
		type type;
	}
}

tag container-tag-name {
	attribute attribute-name; 
		type type;
	}
	# child tag statements here 
}

The following example creates a tag called <traffic-statistics> with an attribute of type string called heading. The tag also contains child tags called <input-bytes> and <output-bytes>.

tag traffic-statistics {
	attribute heading {
		type string;
	}
	tag input-bytes {
		type int;
	}
	tag output-bytes {
		type int;
	}
}

In the following example, the router emits the <traffic-statistics> tag and sets the heading attribute in the opening tag to the string Traffic Statistics. This conveys to the CLI that the string is an appropriate header to use when displaying the contents of the tag.

<traffic-statistics heading="Traffic Statistics">

The ODL compiler generates an index name for each attribute of a tag, and records the index name as part of the tag’s entry in a C-style array of tag names. It creates the array of tag names in the module’s module_odl.h file when the odc command line includes the –u option. The odc command line in the standard ODL Makefile file includes this option. For more information, see Specify a Tag Index Name in Library Files. For discussion of an example, see About the Namespace Attribute.

The compiler derives the index name for an attribute by adding the suffix _ATTR_ATTRIBUTE_NAME to the index name of the tag to which the attribute belongs. The compiler derives the ATTRIBUTE_NAME part of the suffix by converting the name in the ODL attribute statement to all uppercase letters and replacing any hyphens with underscores. For example, the index name for the heading attribute on the <traffic-statistics> tag is ODCI_TRAFFIC_STATISTICS_ATTR_HEADING (assuming that the index name for the tag has the default form ODCI_TRAFFIC_STATISTICS).

Use Predefined JUNOScript Attributes

The generic JUNOScript DTD defines several attributes and makes them available for use by any JUNOS module. Using a predefined attribute requires two steps:

The following sections describe how to use a predefined attribute for the indicated purposes:

Express a Time as a Number of Seconds

The junos:seconds attribute expresses a time as a number of seconds. It is useful not only when you want to display a time value in a form other than seconds (for example, as a number of hours and minutes), but also when you want to perform a calculation on it, such as determining the elapsed time for an event. You record the alternate form as the contents of the tag and use the junos:seconds attribute to represent the corresponding number of seconds.

In the following example, the statement for the <start-time> tag includes an attribute junos:seconds statement.

tag start-time {
	type string;
	attribute junos:seconds;
}

When a JUNOS module emits the <start-time> tag, the contents are a human-readable date value and the junos:seconds attribute represents the equivalent number of seconds since 1 January 1970 (the standard UNIX representation for dates).

<start-time junos:seconds="966816000">
2000-08-21 00:00:00 UTC
</start-time>

For information about altering a JUNOS module’s C program to emit the junos:seconds attribute, see Assign the junos:seconds Attribute.

Express a Temperate in Degrees Celsius

The junos:celsius attribute expresses a temperature in degrees Celsius. This is useful not only when you want the tag’s contents to represent a temperature in both Fahrenheit and Celsius (presumably so that an output display can include both values) but also when you want to enable a program to access the Celsius value without parsing the content of the tag.

In the following example, the statement for the <temperature> tag includes an attribute junos:celsius statement.

tag temperature {
	type string;
	attribute junos:celsius;
}

When a JUNOS module emits the <temperature> tag, the attribute records the temperature in degrees Celsius:

<temperature junos:celsius="29">
29 degrees C / 84 degrees F
</temperature>

For information about altering a JUNOS module’s C program to emit the junos:celcius attribute, see Assign the junos:celsius Attribute.

Specify Other Tag Properties

In addition to the tag properties defined by the type statement and the attributes described in Use Predefined JUNOScript Attributes", you can define other properties for a tag by including other flags, statements, and attributes on its tag statement. For example, the mandatory flag on a child tag indicates that it is required within its container tag. Unlike the type statement, the other kinds of statements can appear inside the tag statements for both container tags and simple tags.

The following list summarizes the available statements and attributes and refers you to the indicated sections for more information. Some sections are in the chapter titled Create Formatting Instructions for the CLI Renderer because the statement or attribute generates formatting instructions for the CLI renderer.

Specify Allowed or Required Number of Child Tags

To indicate the number of instances of a child tag that can or must appear within a container tag, include one of the following flag statements in the child tag’s tag statement:

Create Online Help Statements

To provide descriptions of a tag’s function and contents to be displayed by an online help system, use the help and description statements. The help statement is a brief phrase rather than a complete sentence, and so does not end in a period.The description statement provides more extensive information in one or more complete sentences, each one ending with a period.

For both help and description statements, enclose the text string in quotation marks (" "). To avoid having the terminal wrap strings in an undesirable manner, keep the strings shorter than the common screen width. Do not include newline characters in the strings.

Both simple and container tags can have help and description statements. Although the JUNOS Software does not currently include a fully implemented online help system, you need to provide both of these fields now so that your module is ready when the system is implemented in future.

The syntax for the help and description statements is as follows:

tag tag-name {
	# type statement if a simple tag 
	help "brief help text";
	description "This is description text, which is more detailed 
	than help text";
}

The following example creates online help statements for the <administrative-status> tag. The full set of choice statements actually associated with this tag is omitted for brevity (they appear in enum Type). The description statement appears on two lines here for legibility, but must be unbroken on a single line in the actual ODL file.

tag administrative-status {
	type enum string {
		choice "up" {
		…
		}
	}

	help "The desired state of the interface";
	description "The desired state of the interface. The testing state 
	indicates that no operational packets can be passed.";
}

Specify a Tag Index Name in Library Files

For each XML tag defined in an ODL file, the ODL compiler generates an entry in a C-style array, which your module’s C program can then reference. When the odc command line includes the –u option, the compiler records the array in the module_odl.h file for your module. The odc command line in the standard ODL Makefile file includes this option. For more information about the odc command, see Syntax of the odc Command.

To specify the name that the compiler assigns to a tag’s index in the array, include the define statement within the tag statement. By convention, the DEFINE_NAME string is all uppercase letters and uses underscores to separate words.

tag tag-name {
	# type statement if a simple tag 
	define DEFINE_NAME;
}

If you do not include a define statement, the compiler uses the following conventions to generate the index name:

For example, the default index name for the tag called <output-error-count> is ODCI_OUTPUT_ERROR_COUNT.

Typically, you use the define statement when two conditions apply:

Example: Specify a Tag Index Name

The existing C file #define statements for two router status flags are IFF_PMP and IFF_DEVICEDOWN. Tag names derived directly from these flag names would not comply with ODL tag-naming conventions, which state that tag names use complete words rather than acronyms and use a hyphen between words rather than an underscore. The ODL-compliant name for the tag corresponding to IFF_PMP is <iff-point-to-multipoint/> rather than <iff-pmp/>, and for IFF_DEVICEDOWN is <iff-device-down/> rather than <iff-devicedown/>.

To assign ODL-compliant tag names while also creating #define statements that match the existing #define statements (with the addition of the ODCI_ prefix), use the indicated define statements in the ODL file:

tag iff-point-to-multipoint {
	type empty;
	define ODCI_IFF_PMP;
}
tag iff-device-down {
	type empty;
	define ODCI_IFF_DEVICEDOWN;
}

If you assign the <iff-point-to-multipoint/> and <iff-device-down/> tag names but do not use the ODL define statement, the ODL compiler derives default #define values of ODCI_IFF_POINT_TO_MULTIPOINT and ODCI_DEVICE_DOWN.

Summary of ODL and Resulting DTD Statements

This section summarizes the syntax of the ODL statements discussed in this chapter and describes the DTD statements that result from each one. If you are not interested in the appearance of the XML tags generated by your module, you can ignore the DTD statements.

There are summaries for the indicated entities:

Syntax Summary for Simple tag and type Statements

The syntax for the first instance in the ODL file of a simple or empty tag’s tag statement includes the type statement:

tag tag-name {
	type type;
}

For the empty, int, ipaddr, macaddr, and string types, the type is simply the type name. For the enum type, the syntax statement has additional elements. It takes a subtype argument, for which acceptable values are string and int. Each enclosed choice statement defines one possible value. When subtype is string, you must enclose each possible content value, or choice name, in quotation marks (" "), as shown in the following syntax statement. The quotation marks indicate that each choice name is a single token. Quotation marks are required only when the string contains one or more spaces, but by convention they are always used when the choice name is a character string. For both the string and int subtypes, you always precede the choice name with the string choice.

The enum type also includes a define statement for each choice. The DEFINITION_STRING specifies the name of the #define statement that the ODL compiler generates for the choice and records in the module_odl.h file associated with your JUNOS module.

tag tag-name {
	type enum subtype {
		choice "choice-name" {
			define DEFINITION_STRING;
		}
	}
}

For more information about the output generated by the ODL compiler, see Syntax of the odc Command.

DTD Statements for Simple Tags

The ODL compiler derives an XML !ELEMENT statement of the following form from a simple tag statement. If the odc command line includes the –x option, as it does in the standard ODL Makefile file, the compiler records the !ELEMENT statement in the module’s DTD.

<!ELEMENT tag-name (#PCDATA)>

If the odc command line includes the –v option, as it does in the standard ODL Makefile file, the compiler precedes the !ELEMENT statement with a comment that identifies the element as a tag. As shown in the following DTD syntax statement, XML comments are enclosed by the strings <!-- and -->. The compiler also records the tag’s type in a comment because, as previously noted, XML does not support data typing. It recognizes only one data type, parsed character data, which is indicated by the #PCDATA string in the !ELEMENT statement. This commenting style applies to the empty, int, ipaddr, macaddr, and string types.

<!--TAG tag-name-->
<!--  type: type-->
<!ELEMENT tag-name (#PCDATA)>

For enum types, the compiler creates additional DTD comments to document the choice values. The compiler does not record the DEFINITION_STRING values, which are recorded in the JUNOS module’s module_odl.h file instead. The two choices shown here represent the unlimited number allowed:

tag tag-name {
	type enum subtype {
		choice "choice1" {
			define DEFINITION_STRING1;
		}
		choice "choice2" {
			define DEFINITION_STRING2;
		}
	}
}

<!--TAG tag-name-->
<!--  type: enum subtype-->
<!--    choice: choice1-->
<!--    choice: choice2-->
<!ELEMENT tag-name (#PCDATA)>

Note that multiple ODL statements for the same tag (to define the tag as the child of multiple container tags) do not result in multiple DTD statements. If a subsequent instance of a tag statement includes a new kind of statement (for example, a flag statement), the ODL compiler incorporates the additional information into the existing DTD statement. As previously noted, the ODL file is easier to read when all statements appear in the original statement.

Syntax Summary for Container and Child tag Statements

The statement for a container tag with one simple tag child has the following syntax:

tag container-tag-name {
	tag child-tag-name {
		type type;
	}
}

A container tag’s children can be simple tags, other container tags, or both. You can nest container tags to an unlimited depth. See the example syntax showing four levels of nesting in DTD Statements for Container and Child Tags.

DTD Statements for Container and Child Tags

Recall the statement for a container tag with one simple tag child:

tag container-tag-name {
	tag child-tag-name {
		type type;
	}
}

This statement results in the following two DTD statements, one for the container and one for the child. As for simple tags, a comment precedes each DTD statement if the odc command line includes the –v option (as it does in the standard ODL Makefile file). By default, child-tag-name is marked with a trailing question mark (?) in the !ELEMENT statement for container-tag-name to indicate that zero or one instances of the <child-tag-name> tag can occur within the <container-tag-name> tag. For more information, see Syntax Summary for Attributes.

<!--TAG container-tag-name-->
<!ELEMENT container-tag-name (child-tag-name?)>

<!--TAG child-tag-name-->
<!--  type: type-->
<!ELEMENT child-tag-name (#PCDATA)>

The following example is more complex, with four nested levels. The innermost final-tag statement defines a simple tag and so includes a type statement.

tag container-tag-name {
	tag second-container-tag {
		tag third-container-tag {
			tag final-tag {
				type type;
			}
		}
	}
}

Each tag statement results in a separate DTD statement. Notice that the ODL file makes the nesting relationship between the tags much more obvious than the DTD does.

<!--TAG top-container-tag-->
<!ELEMENT top-container-tag (second-container-tag?)>

<!--TAG second-container-tag-->
<!ELEMENT second-container-tag (third-container-tag?)>

<!--TAG third-container-tag-->
<!ELEMENT third-container-tag (final-tag?)>

<!--TAG final-tag-->
<!--type: type-->
<!ELEMENT final-tag (#PCDATA)>

A container tag can contain an unlimited number of simple or container child tags. The three simple child tags in the following represent the unlimited number:

tag container-tag-name {
	tag child-tag1 {
		type type; 
	}
	tag child-tag2 {
		type type;
	}
	tag child-tag3 {
		type type;
	}
}

The children appear in a comma-separated list in the container tag’s DTD statement, in the same order as their tag statements. There is a separate DTD statement for each child tag as well.

<!--TAG container-tag-name-->
<!ELEMENT container-tag-name (child-tag1?, child-tag2?, child-tag3?)>

<!--TAG child-tag1-->
<!--type: type-->
<!ELEMENT child-tag1 (#PCDATA)>

<!--TAG child-tag2-->
<!--type: type-->
<!ELEMENT child-tag2 (#PCDATA)>

<!--TAG child-tag3-->
<!--type: type-->
<!ELEMENT child-tag3 (#PCDATA)>

Syntax Summary for Attributes

The attribute statement in a tag statement defines an XML attribute. Attributes that you define (as opposed to predefined JUNOScript attributes) have a type just as simple tags do, so their attribute statements must include a type statement of the kind described in Syntax Summary for Simple tag and type Statements. Both simple and container tags can have attributes as indicated in the following syntax statement:

tag simple-tag-name {
	type type;
	attribute attribute-name {
		type type;
	}
}

tag container-tag-name {
	attribute attribute-name {
		type type;
	}
	# child tag statements here 
}

The syntax for a predefined JUNOScript attribute is as follows. Predefined JUNOScript attributes do not have a type.

tag tag-name {
	attribute attribute-name;
}

The possible values for attribute-name are as follows:

DTD Statements for Attributes

An ODL attribute statement is transformed into an !ATTLIST statement in the DTD. By convention, !ATTLIST statements directly follow the !ELEMENT statement for the tag that has the attributes, but this is not strictly necessary because the tag name is repeated in the !ATTLIST statement.

<!--TAG tag-name-->
<!--type: type-->
<!ELEMENT tag-name (#PCDATA)>
<!ATTLIST tag-name attribute-name CDATA #IMPLIED)>

The CDATA field indicates that the attribute’s value is a text string (character data). The #IMPLIED field specifies that the attribute is not required and has no default value. If you are familiar with XML, note that ODL does not include statements that mark an attribute as #REQUIRED or define a default value because those characteristics are not appropriate for attributes on JUNOScript tags.

Syntax Summary for mandatory and multiple Flags

To indicate that a child tag can occur zero or more times in its container tag, include the multiple flag in the child tag’s tag statement.

tag container-tag-name {
	tag child-tag-name {
		type type;
		flag multiple;
	}
}

To indicate that a child tag must occur at least one time in its container tag, include the mandatory and multiple flags in the child tag’s tag statement.

tag container-tag-name {
	tag child-tag-name {
		type type;
		flag multiple mandatory;
	}
}

To indicate that either one or no instances of a child tag can appear, only the type statement is necessary. In other words, this is the default for JUNOScript tags. See Syntax Summary for Simple tag and type Statements.

DTD Statements for mandatory and multiple Flags

When the statement for a child tag child-tag-name includes the multiple flag to indicate that the tag can occur zero or more times, the ODL compiler adds a trailing asterisk (*) to child-tag-name in the !ELEMENT statement for container-tag-name:

<!--TAG container-tag-name-->
<!ELEMENT container-tag-name (child-tag-name*)>

<!--TAG child-tag-name-->
<!--  type: type-->
<!ELEMENT child-tag-name (#PCDATA)>

When the statement for a child tag child-tag-name includes the multiple and mandatory flags to indicate that the tag must occur at least one time, the ODL compiler adds a trailing plus sign (+) to child-tag-name in the !ELEMENT statement for container-tag-name:

<!--TAG container-tag-name-->
<!ELEMENT container-tag-name (child-tag-name+)>

<!--TAG child-tag-name-->
<!--  type: type-->
<!ELEMENT child-tag-name (#PCDATA)>

When the statement for a child tag child-tag-name includes neither the multiple nor mandatory flag to indicate that it can occur one or no times, the ODL compiler adds a trailing question mark (?) to child-tag-name in the !ELEMENT statement for container-tag-name:

<!--TAG container-tag-name-->
<!ELEMENT container-tag-name (child-tag-name?)>

<!--TAG child-tag-name-->
<!--  type: type-->
<!ELEMENT child-tag-name (#PCDATA)>

Syntax Summary for help and description Statements

The help statement is a brief phrase rather than a complete sentence, and so does not end in a period. The description statement provides more extensive information in one or more complete sentences, each one ending with a period.

For both help and description statements, enclose the text string in quotation marks (" "). To avoid having the terminal wrap the string in an undesirable manner, it is best to keep them shorter than the common screen width. Do not include newline characters in them. The syntax for the help and description statements is as follows:

tag tag-name {
	# type statement if a simple tag 
	help "brief help text";
	description "This is description text, which is more detailed than 
	help text.";
} 

DTD Statements for help and description Statements

The contents of ODL help and description statements are recorded in DTD comments:

<!--TAG tag-name-->
<!--type: type      # if a simple tag-->
<!--help: brief help text-->
<!--description: This is description text, which is more detailed than 
help text.-->
<!ELEMENT tag-name (#PCDATA)>

Syntax Summary for define Statement

The syntax for a define statement that defines a tag’s index name in a C array is as follows. Use uppercase letters and underscores to separate words. By convention, the ODCI_ prefix precedes the DEFINE_NAME string.

tag tag-name {
	# type statement if a simple tag 
	define DEFINE_NAME;
}

The ODL compiler does not record the resulting tag index name in the DTD but rather in the module’s module_odl.h file.


© 2007-2009 Juniper Networks, Inc. All rights reserved. The information contained herein is confidential information of Juniper Networks, Inc., and may not be used, disclosed, distributed, modified, or copied without the prior written consent of Juniper Networks, Inc. in an express license. This information is subject to change by Juniper Networks, Inc. Juniper Networks, the Juniper Networks logo, and JUNOS are registered trademarks of Juniper Networks, Inc. in the United States and other countries. All other trademarks, service marks, registered trademarks, or registered service marks are the property of their respective owners.
Generated on Sun May 30 20:26:47 2010 for Juniper Networks Partner Solution Development Platform JUNOS SDK 10.2R1 by Doxygen 1.4.5