mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-04 09:50:54 +00:00
config_tools: walk through xs:alternative
The "xs:alternative" nodes in XML schema enables specifying different types for the same node according to the contents of that node. A typical usage of this construct in the schema of scenario XMLs is to specify different types for a `vm` node depending on whether it is a pre-launched, post-launched or service VMs, so that each VM contains only configurations supported in that kind of VM. This patch adds support of xs:alternative nodes to the schema transformer so that default values can be populated appropriately after we add xs:alternative nodes to the schema. Tracked-On: #6690 Signed-off-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
parent
9f13bbc349
commit
06eacfa32d
@ -5,6 +5,8 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
import elementpath
|
||||
|
||||
class ScenarioTransformer:
|
||||
xpath_ns = {
|
||||
"xs": "http://www.w3.org/2001/XMLSchema",
|
||||
@ -12,20 +14,38 @@ class ScenarioTransformer:
|
||||
|
||||
@classmethod
|
||||
def get_node(cls, element, xpath):
|
||||
return next(iter(element.xpath(xpath, namespaces=cls.xpath_ns)), None)
|
||||
return element.find(xpath, namespaces=cls.xpath_ns)
|
||||
|
||||
def __init__(self, xsd_etree, visit_optional_node=False):
|
||||
self.xsd_etree = xsd_etree
|
||||
|
||||
self._visit_optional_node = visit_optional_node
|
||||
|
||||
def transform_node(self, xsd_element_node, xml_node):
|
||||
complex_type_node = xsd_element_node.find("xs:complexType", namespaces=self.xpath_ns)
|
||||
if not complex_type_node:
|
||||
type_name = xsd_element_node.get("type")
|
||||
if type_name:
|
||||
complex_type_node = self.get_node(self.xsd_etree, f"//xs:complexType[@name='{type_name}']")
|
||||
def type_of_element(self, type_tag, xsd_element_node, xml_node):
|
||||
xsd_alternative_node = xsd_element_node
|
||||
|
||||
if xml_node is not None:
|
||||
for alternative in xsd_element_node.findall("xs:alternative", namespaces=self.xpath_ns):
|
||||
if elementpath.select(xml_node, alternative.get("test")):
|
||||
xsd_alternative_node = alternative
|
||||
break
|
||||
|
||||
type_node = xsd_alternative_node.find(type_tag, namespaces=self.xpath_ns)
|
||||
if type_node is None:
|
||||
type_name = xsd_alternative_node.get("type")
|
||||
if type_name:
|
||||
type_node = self.get_node(self.xsd_etree, f".//{type_tag}[@name='{type_name}']")
|
||||
|
||||
return type_node
|
||||
|
||||
def simple_type_of_element(self, xsd_element_node, xml_node = None):
|
||||
return self.type_of_element("xs:simpleType", xsd_element_node, xml_node)
|
||||
|
||||
def complex_type_of_element(self, xsd_element_node, xml_node = None):
|
||||
return self.type_of_element("xs:complexType", xsd_element_node, xml_node)
|
||||
|
||||
def transform_node(self, xsd_element_node, xml_node):
|
||||
complex_type_node = self.complex_type_of_element(xsd_element_node, xml_node)
|
||||
if complex_type_node is not None:
|
||||
xsd_sequence_node = complex_type_node.find("xs:sequence", namespaces=self.xpath_ns)
|
||||
if xsd_sequence_node is not None:
|
||||
@ -47,7 +67,7 @@ class ScenarioTransformer:
|
||||
self.add_and_transform_missing_node(xsd_element_node, xml_node, new_node_index=index)
|
||||
else:
|
||||
while len(children) > 0 and children[0][1].tag == element_name:
|
||||
self.transform_node(xsd_element_node, children.pop(0)[0])
|
||||
self.transform_node(xsd_element_node, children.pop(0)[1])
|
||||
|
||||
def transform_all(self, xsd_all_node, xml_node):
|
||||
for xsd_element_node in xsd_all_node.findall("xs:element", namespaces=self.xpath_ns):
|
||||
@ -73,6 +93,6 @@ class ScenarioTransformer:
|
||||
|
||||
def transform(self, xml_etree):
|
||||
xml_root_node = xml_etree.getroot()
|
||||
xsd_root_node = self.get_node(self.xsd_etree, f"/xs:schema/xs:element[@name='{xml_root_node.tag}']")
|
||||
xsd_root_node = self.get_node(self.xsd_etree, f".//xs:element[@name='{xml_root_node.tag}']")
|
||||
if xsd_root_node is not None:
|
||||
self.transform_node(xsd_root_node, xml_root_node)
|
||||
|
Loading…
Reference in New Issue
Block a user