XML for NSO - Intermediate
XPath 표현식
- XML 문서에서 하나 이상의 노드를 찾는데 사용되며, 패턴을 사용해 XML 요소의 범위와 다양한 속성을 정의
- 노드 이름 선택자
- 주어진 컨텍스트에서 이름을 기반으로 노드 매칭
devices 노드는 devices에 포함된 모든 요소 반환단일 노드 매칭시 해당 노드의 값을 반환devices | | <devices> <device> <name> Router </name> <id> 151 </id> </device> <devices>
- 주어진 컨텍스트에서 이름을 기반으로 노드 매칭
- 절대 경로와 상대 경로
- 컨텍스트 노드 : 기본적으로 XML 문서의 루트 요소이지만, 처리되는 XPath 표현식에 따라 변경
- 현재 노드 : 마침표 . 기호로 현재 컨텍스트 노드를 참조
- 부모 노드 : 도 개의 마침표 .. 로 현재 노드의 부모를 선택
- 절대 경로 : 현재 컨텍스트 노드와 상관없이 Xpath 표현식 재사용 가능
- 상대 경로 : 전체 구성 트리에 대한 지식이 필요하지 않고 XPah 표현식에서 작업 중인 하위 집한만 알면 사용 가능
XPath를 이용한 데이터 필터링
- XPath는 XML 문서에서 특정 노드를 찾거나 여러 노드를 선택할 때 데이터를 필터링하는 도구
- 이중 슬래시 //
- // 선택자는 문서 내 위치와 상관없이 어디에서든 노드를 선택
- 계층적 수준이나 상위 요소가 다르더라도 일치하는 모든 노드를 찾음
- 다른 표현식과 결합하여 검색 범위를 좁힐 수 있음
/service/devices안에 있는 name 태그 만을 검색/service/devices//name
- 용도
- 다른 데이터 모델을 사용하는 구성에서 작업할 때 유용
- 문서 전체에 공통으로 있는 요소 이름을 찾을 때 사용
- 조건식과 XPath
- 여러 노드 중 특정 노드를 필터링하는 표현식으로 대괄호 []를 사용
- 조건식 유형
- 카운터 사용
- 대괄호 안에 숫자를 넣어 해당 위치의 요소 검색
- 인덱스 1부터 시작
- 예시 : /devices/device[1] → 첫 번째 device 요소 선택
- 속성 필터링
- @ 기호를 사용해 속성의 노드 필터링
- 예시 : //device[@id="router1"] → id 속성이 "router1"인 device 요소 선택
- 와일드카드 연산자
- * - 임의의 노드 매칭
- @* - 임의의 속성 매칭
- 예시 : /config/* → config 하위의 모든 요소 선택
- 요소 값 기반 조건
- 요소의 실제 내용이나 값을 기준으로 노드를 찾을 때 사용
- NSO에서는 특정 이름이나 ID 요소를 찾을 때 특히 유용
- 예시 : /devices/device[name="dist-rtr01"] → name이 "dist-rtr01"인 device 요소 선택
- XPath 함수
- 카운터를 생성할 수도 있는 XPath 함수를 사용해 복잡한 XPath 표현식 형성
- 논리적, 텍스트 처리 지침 등 추가 가능
- 전체 XPath 함수 목록은 온라인 검색 가능
- 카운터 사용
XPath 표현식 연습
- NSO 접속 및 동기화
ncs_cli -C -u developer devices sync-from
- 개발자 도구 활성화 및 표현식 추가
devtools true config xpath eval ?
- XPath 쿼리실행
장치 이름 반환장치 노드 반환xpath eval /devices/device/name
xpath eval /devices/device
XPath operators
- 수치 연산자사용 예시(기본 언어 함수식과 유사)
연산자 설명 +
덧셈 -
빼기 *
곱셈 div
분할 =
동일하다 !=
같지 않다 <
보다 작음 >
보다 크다 >=
크거나 같음 <=
보다 작거나 같음 //subscription[15 > price] //item[(in-stock - 1) >= 0] /vehicles/vehicle[count(.//passenger) > 2] / name concat(//interface[contains(./description, "BANKI")]/type, "-", //interface[contains(./description,"BANKI")]/id) //service[not(state="failed")]
- 방화벽 전체 맵 개수 세기
xpath eval count(/devices/device[name="edge-firewall01"]/config/policy-map)
- 방화벽 INSIDE 네트워크 객체 찾기
xpath eval /devices/device[name='edge-firewall01']/config/object/network[contains(name, 'INSIDE')]/name
- 활성 상태 인터페이스용 XPath 표현삭
developer@ncs(config)# xpath eval /devices/device[name='dist-sw01']/config/ios:interface/GigabitEthernet[not(shutdown)]/name
- 특정 범위 내의 활성 인터페이스 찾기
developer@ncs(config)# xpath eval /devices/device[name='dist-sw01']/config/ios:interface/GigabitEthernet[not(shutdown) and substring(name, 1, 3)='1/' and number(substring(name, 4, 1)) >= 0 and number(substring(name, 4, 1)) <= 9]/name
XML templates에 변수 맵핑하기
- XPath를 사용한 직접 맵핑
XML templatesYANG Model<config-template xmlns="http://tail-f.com/ns/config/1.0" servicepoint="loopback"> <devices xmlns="http://tail-f.com/ns/ncs"> <device> <name>{/device}</name> <config> <interface xmlns="http://tail-f.com/ned/cisco-ios-xr"> <Loopback> <id>{/interface-id}</id> <ipv4> <address> <ip>{/ip-address}</ip> <mask>{/network-mask}</mask> </address> </ipv4> </Loopback> </interface> </config> </device> </devices> </config-template>
서비스 구성 값을 템플릿에 매핑module loopback { namespace "http://com/example/loopback"; prefix loopback; import ietf-inet-types { prefix inet; } import tailf-ncs { prefix ncs; } import tailf-common { prefix tailf; } augment /ncs:services { list loopback { key name; uses ncs:service-data; ncs:servicepoint "loopback"; leaf name { type string; } leaf device { mandatory true; type leafref { path "/ncs:devices/ncs:device/ncs:name"; } } leaf interface-id { mandatory true; type uint32; } leaf ip-address { mandatory true; type inet:ipv4-address; } leaf network-mask { mandatory true; type inet:ipv4-address; } } } }
- 코드에서 변수 매핑하기
- $ 기호를 사용하여 서비스 코드의 매개변수 매핑
<element>{&VALUE}</element>
- template 해당 매개변수 위치에 XPath 변수 사용변수로 관리하기에 더이상 YANG 모델에서는 ip-address와 entwork-mask가 필요하지 않음
<config-template xmlns="http://tail-f.com/ns/config/1.0" servicepoint="loopback"> <devices xmlns="http://tail-f.com/ns/ncs"> <device> <name>{/device}</name> <config> <interface xmlns="http://tail-f.com/ned/cisco-ios-xr"> <Loopback> <id>{/interface-id}</id> <ipv4> <address> <ip>{$IP-ADDRESS}</ip> <mask>{$NETWORK-MASK}</mask> </address> </ipv4> </Loopback> </interface> </config> </device> </devices> </config-template>
대신 Python 코드 등으로 직접 관리ip_address = externalApi.get_address() network_mask = externalApi.get_netmask() tvars = ncs.template.Variables() template = ncs.template.Template(service) tvars.add('IP-ADDRESS', ip_address) tvars.add('NETWORK-MASK', network_mask) template.apply('loopback', tvars)
가능한 template에서 직접 XPath 사용해 작업
XPath를 사용한 직접 매핑이 프로그래밍 코드보다 훨씬 빠름
- $ 기호를 사용하여 서비스 코드의 매개변수 매핑
NSO에서 XPath 대안
- Python & JAVA API
- Python API를 통해 NSO와 상호작용 가능
- ncs 패키지
- maggic 모듈 : 데이터 스토어에 쉽게 액세스 하는 사용
- XPath와 maagic 모듈의 기 유사
- get_root() 모듈을 통해서도 가능
- namespace 처리
NSO 내부 구성의 ncs 사용 가능root.namespace1__object1.namespace2__object2 root.ncs___devices.ncs__device['dist-rtr01']
- maggic 모듈 : 데이터 스토어에 쉽게 액세스 하는 사용