首页 > 解决方案 > 当其中有叶子引用节点时,如何将有效的 YANG 实例数据放入格式良好的 XML 文档中?

问题描述

我在结合两件事时遇到了麻烦:YANG 数据建模和现成的 XML 工具。具体来说,当 YANG 模块对另一个模块有叶子引用时,我看不出如何避免有两个顶级标签。

作为一个精简的例子,考虑这两个 yang 模型和一些有效的实例数据:

杨:

module a {
  namespace "aspace";
  prefix a;

  typedef baz-ref {
    type leafref {
      path "/a:foo/a:bar/a:baz";
    }
  }

  container foo {
    container bar {
      leaf baz {
        type string;
      }
    }
  }
}

b.杨:

module b {
  namespace "bspace";
  prefix b;
  import a {
    prefix a;
  }

  container qux {
    container quux {
      leaf baz {
        type a:baz-ref;
      }
    }
  }
}

有效的.xml:

<?xml version="1.0" encoding="utf-8"?>
<foo xmlns="aspace"><bar><baz>valid</baz></bar></foo>
<qux xmlns="bspace"><quux><baz>valid</baz></quux></qux>

我可以在那个“xml”文件上使用 yanglint:

$ yanglint -s b.yang -t config valid.xml 

但我不能使用例如 Python 的 xml 模块来解析它,因为它有两个顶级标签:

>>> import xml.etree.ElementTree as ET
>>> tree = ET.ElementTree(file='valid.xml')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/xml/etree/ElementTree.py", line 557, in __init__
    self.parse(file)
  File "/usr/lib/python3.6/xml/etree/ElementTree.py", line 597, in parse
    self._root = parser._parse_whole(source)
xml.etree.ElementTree.ParseError: junk after document element: line 3, column 0
>>> 

或者,如果我使用这个 XML,invalid.xml:

<?xml version="1.0" encoding="utf-8"?>
<data xmlns="whatever">
<foo xmlns="aspace"><bar><baz>invalid</baz></bar></foo>
<qux xmlns="bspace"><quux><baz>invalid</baz></quux></qux>
</data>

我可以在 Python(或其他 XML 工具)中很好地解析/创建它:

>>> tree = ET.ElementTree(file='invalid1.xml')
>>> tree
<xml.etree.ElementTree.ElementTree object at 0x7ff4f629ef60>
>>> 

但 yanglint 不喜欢:

$ yanglint -s b.yang -t config invalid1.xml 
err : Unknown element "data". (/)
$

在我正在研究的实际项目中, a.yang 和 b.yang 是 IEEE 标准(来自802.1CBcv,以防细节问题),这意味着我无法触及它们。但我希望有一种方法可以编写一个新的 yang 模块,让我可以将 <foo> 和 <qux> 放在 XML 文件中相同的顶级标记下,并且仍然让 yanglint 根据标准验证实例数据。由于 yang 模块我使用容器而不是分组,我无法弄清楚如何将它们的数据定义作为新 yang 模块中某些更高级别容器的子项导入。

我唯一能做的就是编写多个 .xml 文件,并让 yanglint 合并它们并验证整个数据树,例如:

foo.xml:

<?xml version="1.0" encoding="utf-8"?>
<foo xmlns="aspace"><bar><baz>valid</baz></bar></foo>

qux.xml:

<?xml version="1.0" encoding="utf-8"?>
<qux xmlns="bspace"><quux><baz>valid</baz></quux></qux>

yanglint 命令:

$ yanglint -m -s b.yang -t config foo.xml qux.xml

但是,这些特殊的 yang 模型需要数百个单独的 .xml 文件,因为 ieee802-dot1cb-stream-identification.yang 中的数据定义是一个列表,我们预计该列表中会有很多元素。

这种情况有最佳实践吗?

标签: xmlyang

解决方案


你只是想解析这样的xml文件吗?试试下面的方法。

from simplified_scrapy import SimplifiedDoc, utils

xml = '''<?xml version="1.0" encoding="utf-8"?>
<foo xmlns="aspace"><bar><baz>valid</baz></bar></foo>
<qux xmlns="bspace"><quux><baz>valid</baz></quux></qux>
'''

doc = SimplifiedDoc(xml)
print (doc.foo.baz.text)
print (doc.qux.text)

结果:

valid
valid

推荐阅读