网络自动化运维 Help

6-2 xml格式和jinja2模板渲染

恢复上节服务端

恢复上节课客户端

介绍

XML:(extend mark language可扩展标记语言)是一种用于标记数据的标记语言。纯文本与平台无关,经常用于Java项目中做项配置文件或接口间传输数据。 另一种用途相似的是JSON。

  • 标签Tag: XML使用标签来标记数据,例如 <name>和</name>。 标签通常成对出现,开始标签和结束标签。

  • 元素Element: XML文档由元素组成,元素是包含在开始标签和结束标签之间的数据。 元素可以包含文本、其他元素或两者都包含。

  • 属性Attributes: 属性提供有关元素的额外信息。 属性位于开始标签内,以名称/值对的形式出现。

  • 文档结构: XML文档具有树状结构,其中包含一个根元素和多个子元素。 这种结构允许表示复杂的数据关系。

观察服务器返回的xml配置内容:

<?xml version="1.0" encoding="UTF-8"?> <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <ethernet xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <ethernetIfs> <ethernetIf> <ifName>GE1/0/0</ifName> <ifIndex>5</ifIndex> <l2Enable>enable</l2Enable> <vlanAssigns/> <l2Attribute> <ifIndex>5</ifIndex> <linkType>access</linkType> <pvid>1</pvid> <trunkVlans/> <untagVlans/> <taggedPacketDiscard>false</taggedPacketDiscard> <portBridgEnable>false</portBridgEnable> <portActiveVlanInfos> <portActiveVlanInfo> <unTagVlanList>1</unTagVlanList> <tagVlanList/> </portActiveVlanInfo> </portActiveVlanInfos> <muxVlanEna> <enableVlans/> </muxVlanEna> </l2Attribute> </ethernetIf> <ethernetIf> <ifName>GE1/0/1</ifName> <ifIndex>6</ifIndex> <l2Enable>enable</l2Enable> <vlanAssigns/> <l2Attribute> <ifIndex>6</ifIndex> <linkType>access</linkType> <pvid>1</pvid> <trunkVlans/> <untagVlans/> <taggedPacketDiscard>false</taggedPacketDiscard> <portBridgEnable>false</portBridgEnable> <portActiveVlanInfos> <portActiveVlanInfo> <unTagVlanList>1</unTagVlanList> <tagVlanList/> </portActiveVlanInfo> </portActiveVlanInfos> <muxVlanEna> <enableVlans/> </muxVlanEna> </l2Attribute> </ethernetIf> <ethernetIf> <ifName>GE1/0/2</ifName> <ifIndex>7</ifIndex> <l2Enable>enable</l2Enable> <vlanAssigns/> <l2Attribute> <ifIndex>7</ifIndex> <linkType>access</linkType> <pvid>1</pvid> <trunkVlans/> <untagVlans/> <taggedPacketDiscard>false</taggedPacketDiscard> <portBridgEnable>false</portBridgEnable> <portActiveVlanInfos> <portActiveVlanInfo> <unTagVlanList>1</unTagVlanList> <tagVlanList/> </portActiveVlanInfo> </portActiveVlanInfos> <muxVlanEna> <enableVlans/> </muxVlanEna> </l2Attribute> </ethernetIf> <ethernetIf> <ifName>GE1/0/3</ifName> <ifIndex>8</ifIndex> <l2Enable>enable</l2Enable> <vlanAssigns/> <l2Attribute> <ifIndex>8</ifIndex> <linkType>access</linkType> <pvid>1</pvid> <trunkVlans/> <untagVlans/> <taggedPacketDiscard>false</taggedPacketDiscard> <portBridgEnable>false</portBridgEnable> <portActiveVlanInfos> <portActiveVlanInfo> <unTagVlanList>1</unTagVlanList> <tagVlanList/> </portActiveVlanInfo> </portActiveVlanInfos> <muxVlanEna> <enableVlans/> </muxVlanEna> </l2Attribute> </ethernetIf> <ethernetIf> <ifName>GE1/0/4</ifName> <ifIndex>9</ifIndex> <l2Enable>enable</l2Enable> <vlanAssigns/> <l2Attribute> <ifIndex>9</ifIndex> <linkType>access</linkType> <pvid>1</pvid> <trunkVlans/> <untagVlans/> <taggedPacketDiscard>false</taggedPacketDiscard> <portBridgEnable>false</portBridgEnable> <portActiveVlanInfos> <portActiveVlanInfo> <unTagVlanList>1</unTagVlanList> <tagVlanList/> </portActiveVlanInfo> </portActiveVlanInfos> <muxVlanEna> <enableVlans/> </muxVlanEna> </l2Attribute> </ethernetIf> <ethernetIf> <ifName>GE1/0/5</ifName> <ifIndex>10</ifIndex> <l2Enable>enable</l2Enable> <vlanAssigns/> <l2Attribute> <ifIndex>10</ifIndex> <linkType>access</linkType> <pvid>1</pvid> <trunkVlans/> <untagVlans/> <taggedPacketDiscard>false</taggedPacketDiscard> <portBridgEnable>false</portBridgEnable> <portActiveVlanInfos> <portActiveVlanInfo> <unTagVlanList>1</unTagVlanList> <tagVlanList/> </portActiveVlanInfo> </portActiveVlanInfos> <muxVlanEna> <enableVlans/> </muxVlanEna> </l2Attribute> </ethernetIf> <ethernetIf> <ifName>GE1/0/6</ifName> <ifIndex>11</ifIndex> <l2Enable>enable</l2Enable> <vlanAssigns/> <l2Attribute> <ifIndex>11</ifIndex> <linkType>access</linkType> <pvid>1</pvid> <trunkVlans/> <untagVlans/> <taggedPacketDiscard>false</taggedPacketDiscard> <portBridgEnable>false</portBridgEnable> <portActiveVlanInfos> <portActiveVlanInfo> <unTagVlanList>1</unTagVlanList> <tagVlanList/> </portActiveVlanInfo> </portActiveVlanInfos> <muxVlanEna> <enableVlans/> </muxVlanEna> </l2Attribute> </ethernetIf> <ethernetIf> <ifName>GE1/0/7</ifName> <ifIndex>12</ifIndex> <l2Enable>enable</l2Enable> <vlanAssigns/> <l2Attribute> <ifIndex>12</ifIndex> <linkType>access</linkType> <pvid>1</pvid> <trunkVlans/> <untagVlans/> <taggedPacketDiscard>false</taggedPacketDiscard> <portBridgEnable>false</portBridgEnable> <portActiveVlanInfos> <portActiveVlanInfo> <unTagVlanList>1</unTagVlanList> <tagVlanList/> </portActiveVlanInfo> </portActiveVlanInfos> <muxVlanEna> <enableVlans/> </muxVlanEna> </l2Attribute> </ethernetIf> <ethernetIf> <ifName>GE1/0/8</ifName> <ifIndex>13</ifIndex> <l2Enable>enable</l2Enable> <vlanAssigns/> <l2Attribute> <ifIndex>13</ifIndex> <linkType>access</linkType> <pvid>1</pvid> <trunkVlans/> <untagVlans/> <taggedPacketDiscard>false</taggedPacketDiscard> <portBridgEnable>false</portBridgEnable> <portActiveVlanInfos> <portActiveVlanInfo> <unTagVlanList>1</unTagVlanList> <tagVlanList/> </portActiveVlanInfo> </portActiveVlanInfos> <muxVlanEna> <enableVlans/> </muxVlanEna> </l2Attribute> </ethernetIf> <ethernetIf> <ifName>GE1/0/9</ifName> <ifIndex>14</ifIndex> <l2Enable>enable</l2Enable> <vlanAssigns/> <l2Attribute> <ifIndex>14</ifIndex> <linkType>access</linkType> <pvid>1</pvid> <trunkVlans/> <untagVlans/> <taggedPacketDiscard>false</taggedPacketDiscard> <portBridgEnable>false</portBridgEnable> <portActiveVlanInfos> <portActiveVlanInfo> <unTagVlanList>1</unTagVlanList> <tagVlanList/> </portActiveVlanInfo> </portActiveVlanInfos> <muxVlanEna> <enableVlans/> </muxVlanEna> </l2Attribute> </ethernetIf> </ethernetIfs> </ethernet> <mac xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <globalAttribute> <macAgeTimeEnable>enable</macAgeTimeEnable> <macAgingTime>300</macAgingTime> </globalAttribute> <macUsages> <macUsage> <slot>0</slot> </macUsage> <macUsage> <slot>1</slot> </macUsage> </macUsages> <macflpDetectGlbAttr> <macflpDetectEnable>enable</macflpDetectEnable> <macflpDetectLevel>middle</macflpDetectLevel> <macflpAgingTime>300</macflpAgingTime> <macflpTrapEnable>disable</macflpTrapEnable> <macflpTrapInterval/> </macflpDetectGlbAttr> <macflpDetectExcludeVlan> <vlanLists/> </macflpDetectExcludeVlan> <ifStormContrls> <ifStormContrl> <ifName>GE1/0/0</ifName> <ifIndex>5</ifIndex> <action>normal</action> <trapEnable>disable</trapEnable> <logEnable>disable</logEnable> <interval>5</interval> </ifStormContrl> <ifStormContrl> <ifName>GE1/0/1</ifName> <ifIndex>6</ifIndex> <action>normal</action> <trapEnable>disable</trapEnable> <logEnable>disable</logEnable> <interval>5</interval> </ifStormContrl> <ifStormContrl> <ifName>GE1/0/2</ifName> <ifIndex>7</ifIndex> <action>normal</action> <trapEnable>disable</trapEnable> <logEnable>disable</logEnable> <interval>5</interval> </ifStormContrl> <ifStormContrl> <ifName>GE1/0/3</ifName> <ifIndex>8</ifIndex> <action>normal</action> <trapEnable>disable</trapEnable> <logEnable>disable</logEnable> <interval>5</interval> </ifStormContrl> <ifStormContrl> <ifName>GE1/0/4</ifName> <ifIndex>9</ifIndex> <action>normal</action> <trapEnable>disable</trapEnable> <logEnable>disable</logEnable> <interval>5</interval> </ifStormContrl> <ifStormContrl> <ifName>GE1/0/5</ifName> <ifIndex>10</ifIndex> <action>normal</action> <trapEnable>disable</trapEnable> <logEnable>disable</logEnable> <interval>5</interval> </ifStormContrl> <ifStormContrl> <ifName>GE1/0/6</ifName> <ifIndex>11</ifIndex> <action>normal</action> <trapEnable>disable</trapEnable> <logEnable>disable</logEnable> <interval>5</interval> </ifStormContrl> <ifStormContrl> <ifName>GE1/0/7</ifName> <ifIndex>12</ifIndex> <action>normal</action> <trapEnable>disable</trapEnable> <logEnable>disable</logEnable> <interval>5</interval> </ifStormContrl> <ifStormContrl> <ifName>GE1/0/8</ifName> <ifIndex>13</ifIndex> <action>normal</action> <trapEnable>disable</trapEnable> <logEnable>disable</logEnable> <interval>5</interval> </ifStormContrl> <ifStormContrl> <ifName>GE1/0/9</ifName> <ifIndex>14</ifIndex> <action>normal</action> <trapEnable>disable</trapEnable> <logEnable>disable</logEnable> <interval>5</interval> </ifStormContrl> </ifStormContrls> </mac> <ftpc xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <ftpClient> <sourceIpv4Address/> <sourceInterfaceName/> </ftpClient> </ftpc> <system xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <systemInfo> <sysName>HUAWEI</sysName> <sysContact>R&amp;D Beijing, Huawei Technologies co.,Ltd.</sysContact> <sysLocation>Beijing China</sysLocation> <sysDesc>Huawei Versatile Routing Platform Software &#13; VRP (R) software, Version 8.180 (CE12800 V200R005C10SPC607B607) &#13; Copyright (C) 2012-2018 Huawei Technologies Co., Ltd. &#13; HUAWEI CE12800 &#13; </sysDesc> <sysObjectId>1.3.6.1.4.1.2011.2.62.2.3</sysObjectId> <sysGmtTime>1743421245</sysGmtTime> <sysUpTime>4300</sysUpTime> <sysService>78</sysService> <platformName>VRP</platformName> <platformVer>V800R018C10SPC607</platformVer> <productName>CE12800</productName> <productVer>V200R005C10SPC607</productVer> <patchVer/> <esn>1121232321714418</esn> <mac>707B-E8AB-2C12</mac> <lsRole>admin</lsRole> <authenFlag>false</authenFlag> </systemInfo> </system> <directrt xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <directrtvlink> <drVlinkIfTags> <drVlinkIfTag> <ifName>Vlanif1</ifName> <addressFamily>ipv4uni</addressFamily> <tag>0</tag> </drVlinkIfTag> </drVlinkIfTags> <drVlinkSys> <sysIpv4Enable>false</sysIpv4Enable> <sysIpv6Enable>false</sysIpv6Enable> </drVlinkSys> </directrtvlink> </directrt> <ntp xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <ntpSystemCfg> <maxSessCount>100</maxSessCount> <isAuthEnable>false</isAuthEnable> <isKodEnable>false</isKodEnable> <syncInterval/> <minDiscardIntvl>1</minDiscardIntvl> <avgDiscardIntvl>5</avgDiscardIntvl> <localPort>123</localPort> <maxDistance>1</maxDistance> </ntpSystemCfg> </ntp> <ops xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <assistant> <totalAsstSwitch> <suspend>false</suspend> </totalAsstSwitch> </assistant> </ops> <pp4 xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <globalCfg> <udphelperEnable>false</udphelperEnable> <dscpPriorityValue/> <icmpRateLimitEnable>true</icmpRateLimitEnable> <icmpRateLmtThreshold>1500</icmpRateLmtThreshold> <icmpTtlExdDrpEnable>false</icmpTtlExdDrpEnable> <icmpWithOptDropEnable>false</icmpWithOptDropEnable> <icmpBroadEchoEn>true</icmpBroadEchoEn> <icmpUnrchRevEn>false</icmpUnrchRevEn> </globalCfg> <IpOptSecuritys> <IpOptSecurity> <optionType>routeAlert</optionType> <switchOp>enable</switchOp> </IpOptSecurity> <IpOptSecurity> <optionType>routeRecord</optionType> <switchOp>enable</switchOp> </IpOptSecurity> <IpOptSecurity> <optionType>sourceRoute</optionType> <switchOp>enable</switchOp> </IpOptSecurity> <IpOptSecurity> <optionType>timeStamp</optionType> <switchOp>enable</switchOp> </IpOptSecurity> </IpOptSecuritys> <ReasTimeout> <timeout>30</timeout> </ReasTimeout> </pp4> <radius xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <rdsClient> <isEnable>false</isEnable> <deadCount>10</deadCount> <deadInterval>5</deadInterval> <deadTime>3</deadTime> <failRate>100</failRate> <srvRecoveryOnRspEnable>true</srvRecoveryOnRspEnable> </rdsClient> </radius> <socket xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <TcpGlobalCfg> <tcpFinTimeout>675</tcpFinTimeout> <tcpSynTimeout>75</tcpSynTimeout> <tcpWindow>8</tcpWindow> <tcp6FinTimeout>675</tcp6FinTimeout> <tcp6SynTimeout>75</tcp6SynTimeout> <tcp6Window>8</tcp6Window> <tcpMaxMss/> <tcp6MaxMss/> </TcpGlobalCfg> </socket> <dhcpv6 xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <common> <dhcpv6CommonCfg> <dhcpv6Enable>false</dhcpv6Enable> <remoteIdFormat>default</remoteIdFormat> <remoteIdUserDefineText/> <duidFormat>invalid</duidFormat> <duidString/> <dhcpv6IpsecSa/> <sourceIpAdaptive>false</sourceIpAdaptive> </dhcpv6CommonCfg> </common> <server> <svrCommons> <svrCommon> <dataBaseEnable>false</dataBaseEnable> <dataBaseRecover>false</dataBaseRecover> <writeDelay>86400</writeDelay> </svrCommon> </svrCommons> </server> </dhcpv6> <pp6 xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <Ipv6GlobalCfg> <bucketSize>10</bucketSize> <interval>100</interval> <echoReply>true</echoReply> <hostUnreach>true</hostUnreach> <portUnreach>true</portUnreach> <timeout>10</timeout> <blacklistFlag>false</blacklistFlag> <toobigLimitFlag>true</toobigLimitFlag> </Ipv6GlobalCfg> <icmp6Securitys> <icmp6Security> <action>send</action> <icmpType>0</icmpType> <icmpCode>0</icmpCode> <allFlag>yes</allFlag> <switchOp>enable</switchOp> </icmp6Security> <icmp6Security> <action>receive</action> <icmpType>0</icmpType> <icmpCode>0</icmpCode> <allFlag>yes</allFlag> <switchOp>enable</switchOp> </icmp6Security> </icmp6Securitys> </pp6> <segr xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <srSite> <srEnable>false</srEnable> <srPrefer>false</srPrefer> </srSite> </segr> <vlan xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <vlans> <vlan> <vlanId>1</vlanId> <vlanType>common</vlanType> <vlanName/> <vlanDesc>VLAN 0001</vlanDesc> <adminStatus>up</adminStatus> <subVlans/> <superVlan/> <vlanif> <ifName>Vlanif1</ifName> <cfgBand>1000</cfgBand> <dampTime>0</dampTime> </vlanif> <muxVlan> <separateVlan/> <groupVlans/> </muxVlan> </vlan> </vlans> <instances> <instance> <instanceId>0</instanceId> <vlans> 7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE </vlans> <instanceType>default</instanceType> </instance> </instances> </vlan> <sshc xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <sshClient> <keepAliveTime>0</keepAliveTime> <keepAliveCount>3</keepAliveCount> <firstTimeEnable>Disable</firstTimeEnable> <SrcIpv4Addr/> <SrcInterface/> <vpnInstanceName/> <scpSrcIpv4Addr/> <scpSrcInterface/> <scpVpnInstanceName/> <packetDscp>48</packetDscp> </sshClient> <reKey> <rekeyMaxPacketNo>2147483648</rekeyMaxPacketNo> <rekeyTime>60</rekeyTime> <rekeyMaxData>1000</rekeyMaxData> </reKey> <sshCCipherAlg> <descbc>false</descbc> <des3cbc>true</des3cbc> <aes128cbc>true</aes128cbc> <aes256cbc>true</aes256cbc> <aes128ctr>true</aes128ctr> <aes192ctr>true</aes192ctr> <aes256ctr>true</aes256ctr> <arcfour128>false</arcfour128> <arcfour256>false</arcfour256> <aes128gcm>true</aes128gcm> <aes256gcm>true</aes256gcm> <aes192cbc>false</aes192cbc> </sshCCipherAlg> <sshcKexAlg> <dhGroupExchangeSha256>true</dhGroupExchangeSha256> <dhGroupExchangeSha1>true</dhGroupExchangeSha1> <dhGroup1Sha1>true</dhGroup1Sha1> <ecdhSha2Nistp256>true</ecdhSha2Nistp256> <ecdhSha2Nistp384>true</ecdhSha2Nistp384> <ecdhSha2Nistp521>true</ecdhSha2Nistp521> <sm2Kep>true</sm2Kep> <dhGroup14Sha1>true</dhGroup14Sha1> </sshcKexAlg> <sshCHMacAlg> <md5>true</md5> <md596>true</md596> <sha1>true</sha1> <sha196>true</sha196> <sha2256>true</sha2256> <sha225696>true</sha225696> <sha2512>true</sha2512> </sshCHMacAlg> <sshCPubKeyAlg> <dsa>true</dsa> <ecc>true</ecc> <rsa>true</rsa> </sshCPubKeyAlg> </sshc> <isiscomm xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <isisGlobalCfg> <lspSeqOverAutoRvFlag>true</lspSeqOverAutoRvFlag> <sysIdConflictAutoRvFlag>true</sysIdConflictAutoRvFlag> <purgeLspProtectEnable>true</purgeLspProtectEnable> </isisGlobalCfg> </isiscomm> <rtp xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <rtpGlobal> <nonexistentCheckFlag>true</nonexistentCheckFlag> </rtpGlobal> </rtp> <cli xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <headerInfo> <loginInfo> <loginInfoType/> <loginText/> <loginFile/> </loginInfo> <shellInfo> <shellInfoType/> <shellText/> <shellFile/> </shellInfo> </headerInfo> </cli> <efm xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> <efmGlobalCfg> <efmGlobalEnable>false</efmGlobalEnable> <loopIndex/> <isSendPacket>0</isSendPacket> <sessionId>0</sessionId> <ifName/> </efmGlobalCfg> <efmInterfaces> <efmInterface> <ifName>GE1/0/0</ifName> <state>disable</state> <mode>active</mode> <maxPduCfg>128</maxPduCfg> <errFramePeriod>1</errFramePeriod> <errFrameThresh>1</errFrameThresh> <errFrameNotify>disable</errFrameNotify> <errFrmSecPeriod>60</errFrmSecPeriod> <errFrmSecThresh>1</errFrmSecThresh> <errFrmSecNotify>disable</errFrmSecNotify> <errCodePeriod>1</errCodePeriod> <errCodeThresh>1</errCodeThresh> <errCodeNotify>disable</errCodeNotify> <triggerIfDown>disable</triggerIfDown> <interval>1000</interval> <timeout>5000</timeout> <holdUpTime>0</holdUpTime> <ignoreRequest>disable</ignoreRequest> </efmInterface> <efmInterface> <ifName>GE1/0/1</ifName> <state>disable</state> <mode>active</mode> <maxPduCfg>128</maxPduCfg> <errFramePeriod>1</errFramePeriod> <errFrameThresh>1</errFrameThresh> <errFrameNotify>disable</errFrameNotify> <errFrmSecPeriod>60</errFrmSecPeriod> <errFrmSecThresh>1</errFrmSecThresh> <errFrmSecNotify>disable</errFrmSecNotify> <errCodePeriod>1</errCodePeriod> <errCodeThresh>1</errCodeThresh> <errCodeNotify>disable</errCodeNotify> <triggerIfDown>disable</triggerIfDown> <interval>1000</interval> <timeout>5000</timeout> <holdUpTime>0</holdUpTime> <ignoreRequest>disable</ignoreRequest> </efmInterface> <efmInterface> <ifName>GE1/0/2</ifName> <state>disable</state> <mode>active</mode> <maxPduCfg>128</maxPduCfg> <errFramePeriod>1</errFramePeriod> <errFrameThresh>1</errFrameThresh> <errFrameNotify>disable</errFrameNotify> <errFrmSecPeriod>60</errFrmSecPeriod> <errFrmSecThresh>1</errFrmSecThresh> <errFrmSecNotify>disable</errFrmSecNotify> <errCodePeriod>1</errCodePeriod> <errCodeThresh>1</errCodeThresh> <errCodeNotify>disable</errCodeNotify> <triggerIfDown>disable</triggerIfDown> <interval>1000</interval> <timeout>5000</timeout> <holdUpTime>0</holdUpTime> <ignoreRequest>disable</ignoreRequest> </efmInterface> <efmInterface> <ifName>GE1/0/3</ifName> <state>disable</state> <mode>active</mode> <maxPduCfg>128</maxPduCfg> <errFramePeriod>1</errFramePeriod> <errFrameThresh>1</errFrameThresh> <errFrameNotify>disable</errFrameNotify> <errFrmSecPeriod>60</errFrmSecPeriod> <errFrmSecThresh>1</errFrmSecThresh> <errFrmSecNotify>disable</errFrmSecNotify> <errCodePeriod>1</errCodePeriod> <errCodeThresh>1</errCodeThresh> <errCodeNotify>disable</errCodeNotify> <triggerIfDown>disable</triggerIfDown> <interval>1000</interval> <timeout>5000</timeout> <holdUpTime>0</holdUpTime> <ignoreRequest>disable</ignoreRequest> </efmInterface> <efmInterface> <ifName>GE1/0/4</ifName> <state>disable</state> <mode>active</mode> <maxPduCfg>128</maxPduCfg> <errFramePeriod>1</errFramePeriod> <errFrameThresh>1</errFrameThresh> <errFrameNotify>disable</errFrameNotify> <errFrmSecPeriod>60</errFrmSecPeriod> <errFrmSecThresh>1</errFrmSecThresh> <errFrmSecNotify>disable</errFrmSecNotify> <errCodePeriod>1</errCodePeriod> <errCodeThresh>1</errCodeThresh> <errCodeNotify>disable</errCodeNotify> <triggerIfDown>disable</triggerIfDown> <interval>1000</interval> <timeout>5000</timeout> <holdUpTime>0</holdUpTime> <ignoreRequest>disable</ignoreRequest> </efmInterface> <efmInterface> <ifName>GE1/0/5</ifName> <state>disable</state> <mode>active</mode> <maxPduCfg>128</maxPduCfg> <errFramePeriod>1</errFramePeriod> <errFrameThresh>1</errFrameThresh> <errFrameNotify>disable</errFrameNotify> <errFrmSecPeriod>60</errFrmSecPeriod> <errFrmSecThresh>1</errFrmSecThresh> <errFrmSecNotify>disable</errFrmSecNotify> <errCodePeriod>1</errCodePeriod> <errCodeThresh>1</errCodeThresh> <errCodeNotify>disable</errCodeNotify> <triggerIfDown>disable</triggerIfDown> <interval>1000</interval> <timeout>5000</timeout> <holdUpTime>0</holdUpTime> <ignoreRequest>disable</ignoreRequest> </efmInterface> <efmInterface> <ifName>GE1/0/6</ifName> <state>disable</state> <mode>active</mode> <maxPduCfg>128</maxPduCfg> <errFramePeriod>1</errFramePeriod> <errFrameThresh>1</errFrameThresh> <errFrameNotify>disable</errFrameNotify> <errFrmSecPeriod>60</errFrmSecPeriod> <errFrmSecThresh>1</errFrmSecThresh> <errFrmSecNotify>disable</errFrmSecNotify> <errCodePeriod>1</errCodePeriod> <errCodeThresh>1</errCodeThresh> <errCodeNotify>disable</errCodeNotify> <triggerIfDown>disable</triggerIfDown> <interval>1000</interval> <timeout>5000</timeout> <holdUpTime>0</holdUpTime> <ignoreRequest>disable</ignoreRequest> </efmInterface> <efmInterface> <ifName>GE1/0/7</ifName> <state>disable</state> <mode>active</mode> <maxPduCfg>128</maxPduCfg> <errFramePeriod>1</errFramePeriod> <errFrameThresh>1</errFrameThresh> <errFrameNotify>disable</errFrameNotify> <errFrmSecPeriod>60</errFrmSecPeriod> <errFrmSecThresh>1</errFrmSecThresh> <errFrmSecNotify>disable</errFrmSecNotify> <errCodePeriod>1</errCodePeriod> <errCodeThresh>1</errCodeThresh> <errCodeNotify>disable</errCodeNotify> <triggerIfDown>disable</triggerIfDown> <interval>1000</interval> <timeout>5000</timeout> <holdUpTime>0</holdUpTime> <ignoreRequest>disable</ignoreRequest> </efmInterface> <efmInterface> <ifName>GE1/0/8</ifName> <state>disable</state> <mode>active</mode> <maxPduCfg>128</maxPduCfg> <errFramePeriod>1</errFramePeriod> <errFrameThresh>1</errFrameThresh> <errFrameNotify>disable</errFrameNotify> <errFrmSecPeriod>60</errFrmSecPeriod> <errFrmSecThresh>1</errFrmSecThresh> <errFrmSecNotify>disable</errFrmSecNotify> <errCodePeriod>1</errCodePeriod> <errCodeThresh>1</errCodeThresh> <errCodeNotify>disable</errCodeNotify> <triggerIfDown>disable</triggerIfDown> <interval>1000</interval> <timeout>5000</timeout> <holdUpTime>0</holdUpTime> <ignoreRequest>disable</ignoreRequest> </efmInterface> </efmInterfaces> </efm> </data>

提问,说出哪一部分是元素、属性。

ncclient上传配置

题目:配置GE1/0/2口的IP为10.1.1.1/24

如果在设备端操作将是:

# 不要运行这几句。实验目的是通过python客户端走netconf协议上传xml配置文件实现同样效果。 [CE1]int g1/0/2 [CE1-GE1/0/2]undo portswitch # 关闭2层,启⽤3层 [CE1-GE1/0/2]ip address 10.1.1.1 255.255.255.0 [CE1-GE1/0/2

华为官方文档-CE12800-netconf协议

  1. xml模板:
    netconf协议修改设备的xml模板在设备官网文档中可查询到。
    正规做法是保存内容到本地文件,运行python代码时open打开内容。但因为内容不多,也可以直接把模板内容放入声明的字符串变量中。

    <config> <ethernet xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0"> <ethernetIfs> <ethernetIf operation="merge"> <ifName>GE1/0/2</ifName> <l2Enable>disable</l2Enable> </ethernetIf> </ethernetIfs> </ethernet> <ifm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0"> <interfaces> <interface operation="merge"> <ifName>GE1/0/2</ifName> <ifAdminStatus>up</ifAdminStatus> <ifDescr>Config by NETCONF</ifDescr> <ifmAm4> <am4CfgAddrs> <am4CfgAddr operation="merge"> <subnetMask>255.255.255.0</subnetMask> <addrType>main</addrType> <ifIpAddr>10.1.1.1</ifIpAddr> </am4CfgAddr> </am4CfgAddrs> </ifmAm4> </interface> </interfaces> </ifm> </config>

    一些标签属性解释:

    • <edit-config>操作用来把全部或部分配置数据加载到指定的目标配置数据库(<running/>)。设备对<edit-config>中的操作进行鉴权,鉴权通过后,执行相应的修改。

    • merge:在数据库中修改存在或不存在的目标数据,如果目标数据不存在则创建,如果目标数据存在则修改。这是默认操作。

    • target:待编辑的配置数据库。基于场景选择对应的数据库,立即生效模式,配置数据库为<running/>。

    • error-option rollback-on-error:出现错误后停止操作,并将配置回退到执行<edit-config>操作之前的状态。只有设备支持rollback-on-error能力才支持此操作。

      6 2pycharm
      6 2pycharm 2

  2. python代码

    CREATE_INTERFACE2 = ''' <config> <ethernet xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0"> <ethernetIfs> <ethernetIf operation="merge"> <ifName>GE1/0/2</ifName> <l2Enable>disable</l2Enable> </ethernetIf> </ethernetIfs> </ethernet> <ifm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0"> <interfaces> <interface operation="merge"> <ifName>GE1/0/2</ifName> <ifAdminStatus>up</ifAdminStatus> <ifDescr>Config by NETCONF</ifDescr> <ifmAm4> <am4CfgAddrs> <am4CfgAddr operation="create"> <subnetMask>255.255.255.0</subnetMask> <addrType>main</addrType> <ifIpAddr>10.1.1.1</ifIpAddr> </am4CfgAddr> </am4CfgAddrs> </ifmAm4> </interface> </interfaces> </ifm> </config> ''' from ncclient import manager with manager.connect( host='192.168.56.100', port=830, username='zhangsan', password='Huawei@123', hostkey_verify=False, device_params={'name':'huawei'} ) as m: # 上传配置 rs = m.edit_config(target='running', config=CREATE_INTERFACE2) print(rs)
  3. 服务端查看效果

    <HUAWEI>display ip interface brief

    观察到两个vlan口有ip。

    可能有人会有疑问,通过python控制模板比在设备端终端里输入几行命令复杂。
    但配置文件的优点有:

    • 字段除了能配置IP还有许多其它功能,功能复杂时更有优势。

    • 命令会输错,配置确定稳定后就不会错。

    • 配置文件搭配编程语言,方便扩散到多台设备上。

    6 2ncclient

Jinja2

一个配置文件内容很多,上面只是一个接口的IP配置部分。当有多个设备时,把配置文件写死是一种耗费精力和不易于维护的做法。
正确的做法是将配置收集到一个配置文件中或Python的列表、字典数据结构中:

devices = [ { 'name': 'S01', 'model': 'CE12800', 'ip': '192.168.56.100', 'username': 'zhangsan', 'password': 'Huawei@123', 'interfaces': [ { 'name': 'GE1/0/2', 'ip': '10.0.0.1/24' } ] }, { 'name': 'S02', 'model': 'S5700', 'ip': '192.168.56.101', 'username': 'zhangsan', 'password': 'Huawei@123', 'interfaces': [ { 'name': 'GE1/0/2', 'ip': '10.0.0.2/24' } ] } ]

然后把数据塞到模板中,模板中需要填入数据的地方,用特殊语法扣一个空。
Jinja2是python生态中完成这项工作的最流行的库之一,其它编程语言也都有类似的库。

为了简化,不再演示把网工数据填入模板(可查看课本上这章相关内容),下面的基础例子演示了Jinja2例子。

  1. 新建template.xml ,与后面创建的py脚本处于同一目录下。
    用下面的简单数据例子来代替网工数据和课本上本章大量的xml模版。

    <!--这部分代码不用敲,直接用下一步含Jinja2语法的。--> <users> <user id="1"> <name>xiaoming</name> <email>11111@qq.com</email> </user> <user id="2"> <name>xiaoming</name> <email>22222@qq.com</email> </user> </users>
  2. 然后把重复的地方抽离出来,在想要插入值的地方用Jinja2语法。{{}}语法表示插入值。{% %}可以书写部分简易Python语句如循环。 Jinja2的思想,在于解析包含Jinja2特殊语法的xml,把后端数据渲染到xml中。

    <users> {% for user in users %} <user id="{{ user.id }}"> <name>{{ user.name }}</name> <email>{{ user.email }}</email> </user> {% endfor %} </users>
  3. 安装jinja2库

    pip install jinja2
  4. python代码

    from jinja2 import Environment, FileSystemLoader # 准备数据。xml模板和jinja2渲染应该与此结构保持一致。 users = [ {"id": 1, "name": "Alice", "email": "alice@example.com"}, {"id": 2, "name": "Bob", "email": "bob@example.com"}, {"id": 3, "name": "Charlie", "email": "charlie@example.com"}, ] # 配置Jinja2环境 env = Environment(loader=FileSystemLoader(".")) # 待渲染的模板。注意文件名与实际创建的文件名保持一致。 template = env.get_template("./template.xml") # 传入后端数据到带有jinja语法的模板中,最终渲染得到结果xml内容。 rendered_xml = template.render(users=users) print(rendered_xml) # 可选:将渲染后的XML保存到文件 with open("./rendered.xml", "w") as f: f.write(rendered_xml)
  5. 检查渲染结果,应该如下

    <users> <user id="1"> <name>Alice</name> <email>alice@example.com</email> </user> <user id="2"> <name>Bob</name> <email>bob@example.com</email> </user> <user id="3"> <name>Charlie</name> <email>charlie@example.com</email> </user> </users>
    6 2jinja2 xml

xml解析

主要场景:

  1. 从接口收到数据,解析拿出字段值再组装成需要的结构存入数据库。

  2. 爬虫程序解析网页html。

与Json类似,略微不同之处是Json转python内置数据结构和python内置结构转Json两种操作都经常用,而xml在python生态主要是xml转python内置结构,因为python生态的接口数据传输主要用json。

内置库解析

内置库叫xml库,功能比较基础,在解析html复杂标签时可能需要自定义类,比较麻烦。
文档树(DOM):ElementTree会降xml解析成树状结构再取值。

import xml.etree.ElementTree as ET # 假设已经从接口或爬虫获取到了一些xml格式的字符串数据。 xml_string = """ <root> <person> <name>张三</name> <age>30</age> <city>北京</city> </person> <person> <name>李四</name> <age>25</age> <city>上海</city> </person> </root> """ root = ET.fromstring(xml_string) data = [] for person in root.findall('person'): person_data = { 'name': person.find('name').text, 'age': int(person.find('age').text), 'city': person.find('city').text, } data.append(person_data) print(data)

三方库lxml

这是一个C语言写的库,pip安装时会下载适合当前操作系统和Python解释器版本的编译后的二进制版本,而不需要电脑上安装C编译器和编译。
相比内置库,解析速度和功能都更加强大。
安装pip install lxml
xPath表达式: (课外)表示xml标签层级的特殊语法,可以用来表示想要解析和取值的位置。

from lxml import etree xml_string = """ <root> <person> <name>张三</name> <age>30</age> <city>北京</city> </person> <person> <name>李四</name> <age>25</age> <city>上海</city> </person> </root> """ root = etree.fromstring(xml_string) data = [] for person in root.xpath('//person'): # 使用 XPath 查找 person 元素 person_data = { 'name': person.xpath('string(name)'), # 使用 XPath string() 提取文本 'age': int(person.xpath('string(age)')), 'city': person.xpath('string(city)'), } data.append(person_data) print(data)

课外

  • 使用bs4、regex、xpath几种不同方式解析xml格式文件。

  • 寻找netconf图形化工具。

  • 尝试知名Web框架Flask框架,与Jinja2同一个团队并集成。(对于软件专业同学没什么,对于网工专业同学会有点难)

  • 尝试用Python自带的字符串拼接语法和循环,达到jinja2的基本功能。

参考

CloudEngine 12800 V200R022C10 配置指南-网络管理与监控

08 四月 2025