As mentioned in the previous section, Getting Access to Node Names, you can get access to all child elements of a node by right-clicking the node and selecting the Show Child Elements with Dynamic Name context menu command. At mapping runtime, this causes the name of each child element to be accessible through the node-name() node, while the value—through a special type cast node. In the image below, the type cast node is the text() node.
Importantly, the data type of each child element is not known before the mapping runtime. Besides, it may be different for each child element. For example, a product node in the XML instance file may have a child element id of type xs:integer and a child element size of type xs:string. To let you access the node content of a specific type, the dialog box shown below opens every time when you enable dynamic access to a node's child elements. You can also open this dialog box at any time later, by clicking the Change Selection ( ) button next to the element() node.
"Dynamically Named Children Settings" dialog box
To access the content of each child element at mapping runtime, you have several options:
1.Access the content as string. To do this, select the text() check box on the dialog box above. In this case, a text() node is created on the component when you close the dialog box. This option is suitable if the content is of simple type (xs:int, xs:string, etc.) and is illustrated in the Example: Map Element Names to Attribute Values. Note that a text() node is displayed only if a child node of the current node can contain text.
2.Access the content as a particular complex type allowed by the schema. When custom complex types defined globally are allowed by the schema for the selected node, they are also available in the dialog box above, and you can select the check box next to them. In the image above, there are no complex types defined globally by the schema, so none are available for selection.
3.Access the content as any type. This may be useful in advanced mapping scenarios (see "Accessing deeper structures" below). To do this, select the check box next to xs:anyType.
Be aware that, at mapping runtime, MapForce (through the type cast node) has no information as to what the actual type of the instance node is. Therefore, your mapping must access the node content using the correct type. For example, if you expect that the node of a source XML instance may have children nodes of various complex types, do the following:
a) Set the type cast node to be of the complex type that you need to match (see item 2 in the list above).
b) Add a filter to read from the instance only the complex type that you need to match. This technique is illustrated in Example: Group and Filter Nodes by Name.
Accessing deeper structures
It is possible to access nodes at deeper levels in the schema than the immediate children of a node. It is useful for advanced mapping scenarios. In simple mappings such as Example: Map Element Names to Attribute Values, you don't need this technique because the mapping accesses only the immediate children of an XML node. However, if you need to access deeper structures dynamically, such as "grandchildren", "grand-grandchildren", and so on, this is possible as shown below.
1.Create a new mapping.
2.On the Insert menu, click Insert XML Schema/File and browse for the XML instance file (in this example, the Articles.xml file from the <Documents>\Altova\MapForce2020\MapForceExamples\Tutorial\ folder).
3.Right-click the Articles node and select the Show Child Elements with Dynamic Name context command.
4.Select xs:anyType from the "Dynamically Named Children Settings" dialog box.
5.Right-click the xs:anyType node and select again the Show Child Elements with Dynamic Name context command.
6.Select text() from the "Dynamically Named Children Settings" dialog box.
In the component above, notice there are two element() nodes. The second element() node provides dynamic access to grandchildren of the <Articles> node in the Articles.xml instance.
<?xml version="1.0" encoding="UTF-8"?>
For example, to get "grandchildren" element names (Number, Name, SinglePrice), you would draw a connection from the local-name() node under the second element() node to a target item. Likewise, to get "grandchildren" element values (1, T-Shirt, 25), you would draw a connection from the text() node.
Although not applicable to this example, in real-life situations, you can further enable dynamic node names for any subsequent xs:anyType node, so as to reach even deeper levels.
Note the following:
•The button allows you to select any derived type from the current schema and display it in a separate node. This may only be useful if you need to map to or from derived schema types (see Derived XML Schema Types).
•The Change Selection ( ) button next to an element() node opens the "Dynamically Named Children Settings" dialog box discussed in this topic.
•The Change Selection ( ) button next to xs:anyAttribute allows you to select any attribute defined globally in the schema. Likewise, the Change Selection ( ) button next to xs:any element allows you to select any element defined globally in the schema. This works in the same way as mapping to or from schema wildcards (see also Wildcards - xs:any / xs:anyAttribute). If using this option, make sure that the selected attribute or element can actually exist at that particular level according to the schema.