2016-10-24 14 views
1

妥当なpythonの新機能と、それを解析しようとするよりはるかに少ないxmlの新機能一連のweblogic xml設定ファイルからクラスタノードを特定する必要があります。私はそれらの75%を得る方法を考え出しました。今、私は最悪の場合を追いかけており、どのように進むべきかは分かりません。python lxml&xpathで始まる?

Weblogicのxml設定ファイルは名前空間の定義で始まり、いくつかの子要素は独自の子要素を持ちます。

私が興味を持っている要素は<server>です。通常は、私が探しているホスト名を含む<listen-address>というサブ要素があります。

「私たちは標準が大好きです」というパラダイムに続いて、このモデルはどこでも動作しません。それがうまくいかない場合、私は<server>のサブ要素、すなわち<machine>を探す必要があります。その要素には別のルートの子に展開されたエイリアスが含まれ、同じレベルの<server>です。

だから、千個の言葉よりも雄弁写真:

注:XMLのトンを送るのを避けるためにしようとしていました。しかし、明らかに、帯域幅を節約しようとする私の試みは、この問題を解決するのを難しくしています。謝罪。私は不必要なセキュリティやセキュリティ関連の子要素を整理しました。

<?xml version='1.0' encoding='UTF-8'?> 
<domain xmlns="http://xmlns.oracle.com/weblogic/domain" xmlns:sec="http://xmlns.oracle.com/weblogic/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wls="http://xmlns.oracle.com/weblogic/security/wls" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/security/wls http://xmlns.oracle.com/weblogic/security/wls/1.0/wls.xsd http://xmlns.oracle.com/weblogic/domain http://xmlns.oracle.com/weblogic/1.0/domain.xsd http://xmlns.oracle.com/weblogic/security/xacml http://xmlns.oracle.com/weblogic/security/xacml/1.0/xacml.xsd http://xmlns.oracle.com/weblogic/security/providers/passwordvalidator http://xmlns.oracle.com/weblogic/security/providers/passwordvalidator/1.0/passwordvalidator.xsd http://xmlns.oracle.com/weblogic/security http://xmlns.oracle.com/weblogic/1.0/security.xsd"> 
    <name>EDIServices_Domain</name> 
    <domain-version>12.2.1.0.0</domain-version> 
    <security-configuration> 
    <name>EDIServices_Domain</name> 
    <default-realm>myrealm</default-realm> 
    <node-manager-username>snipped</node-manager-username> 
    <node-manager-password-encrypted>not_really_my_pwd</node-manager-password-encrypted> 
    </security-configuration> 
    <server> 
    <name>EDIServices_AS</name> 
    <listen-port>60010</listen-port> 
    <web-server> 
     <name>EDIServices_AS</name> 
     <web-server-log> 
     <file-name>/opt/app/oracle/user_projects/logs/EDIServices_Domain/access.log</file-name> 
     <file-count>24</file-count> 
     <file-min-size>10000</file-min-size> 
     <rotate-log-on-startup>true</rotate-log-on-startup> 
     <elf-fields>c-ip cs-uri date time cs-method cs-uri sc-status</elf-fields> 
     <log-file-format>common</log-file-format> 
     </web-server-log> 
    </web-server> 
    <listen-address></listen-address> 
    </server> 
    <server> 
    <name>EDIServices_MS1</name> 
    <machine>EDIServices_MC1</machine> 
    <listen-port>60014</listen-port> 
    <cluster>EDIServices_CS</cluster> 
    <listen-address></listen-address> 
    </server> 
    <server> 
    <name>EDIServices_MS2</name> 
    <machine>EDIServices_MC2</machine> 
    <listen-port>60014</listen-port> 
    <cluster>EDIServices_CS</cluster> 
    <listen-address></listen-address> 
    </server> 
    <cluster> 
    <name>EDIServices_CS</name> 
    <cluster-messaging-mode>unicast</cluster-messaging-mode> 
    <dynamic-servers> 
     <maximum-dynamic-server-count>0</maximum-dynamic-server-count> 
    </dynamic-servers> 
    </cluster> 
    <production-mode-enabled>true</production-mode-enabled> 
    <configuration-version>12.2.1.0.0</configuration-version> 
<machine xsi:type="unix-machineType"> 
    <name>EDIServices_MC1</name> 
    <node-manager> 
     <name>EDIServices_MC1</name> 
     <nm-type>SSL</nm-type> 
     <listen-address>host001</listen-address> 
     <listen-port>7001</listen-port> 
    </node-manager> 
    </machine> 
    <machine xsi:type="unix-machineType"> 
    <name>EDIServices_MC2</name> 
    <node-manager> 
     <name>EDIServices_MC2</name> 
     <listen-address>host002</listen-address> 
     <listen-port>7001</listen-port> 
    </node-manager> 
    </machine> 
</domain> 

ので、 '通常' の設定でそれを実行している、私が手:

$ ./lxml configs/EntsvcSoa_Domain_config.xml 
EntsvcSoa_AS => host003.myco.com 
EntsvcSoa_MS1 => host004.myco.com 
EntsvcSoa_MS2 => host005.myco.com 

ABI-通常の設定に対してそれを実行して、私は現在取得しています:

$ ./lxml configs/EDIServices_Domain_config.xml 
EDIServices_MS1 => EDIServices_MC1 
EDIServices_MS2 => EDIServices_MC2 

使い方上記の例では、EDIServices_MC1とEDIServices_MC2をそれぞれhost001とhost002に翻訳したいと考えています。

次ループは次のとおりです。

注:完全であることの利益のために、ここでは全体のスクリプトは次のとおりです。

#!/usr/bin/env python3 

from lxml import etree 
import re 
import sys 
import os 
import pprint 

if len(sys.argv) != 2: 
    print('Format: ./wl_clusters ${weblogic_config_file}') 
    sys.exit(1) 

if not os.path.isfile(sys.argv[1]): 
    print('Format: ./wl_clusters ${weblogic_config_file}') 
    sys.exit(2) 

config = sys.argv[1] 

# set up lxml structures 
tree = etree.parse(config) 
root = tree.getroot() 

# set up xml namespace govno 
ns = root.nsmap[None] 
namespaces = { 'ns': ns } 

for server in root.findall('ns:server', namespaces): 
    cs = server.find('ns:cluster', namespaces) 
    if cs is None: 
    continue 
    # cluster_name = server.find('ns:cluster', namespaces).text 
    cluster_name = cs.text 
    listen_address = server.find('ns:listen-address', namespaces) 
    server_name = listen_address.text 
    if server_name is None: 
    machine = server.find('ns:machine', namespaces) 
    if machine is None: 
     continue 
    else: 
     server_name = machine.text 

    print("%-15s => %s" % (cluster_name, server_name)) 

(コードの12行を書くために私にを取っています...良いこと私は生きもののためにこれをしない:))

言い換えれば、<server>子供の名前に一致する名前の子<machine>の下にあるを見つける必要があります。ウェブ上のいくつかの例から、私はxpathが助けてくれるかもしれないと信じていますが、私は単純な例を作業することさえできませんでした。私はちょうど名前空間が何であるか把握しました...

xpathの完全なnoobチュートリアルでは、ヒント/ヒント/提案が特に高く評価されました。

お時間をいただきありがとうございます。

ダグ・オリアリーは

+1

xmlの使用可能なスニペットを追加してください –

+0

要素はxmlファイルあたり1つですか、それらの数は多いですか? – Muposat

+0

有効なXMLサンプル文書を提供します。特に、すべての名前空間宣言が含まれています。これは重要。 – Markus

答えて

-1

はここにあなたのファイルでXPathを使用した例です。私はすべての要素「ドメイン」を処理し、「*の名前」を表示します。これらの名前は、同じレベル内にあるので機能します。

from lxml import etree 
xp = etree.XPath('./*/name') 
for event, elem in etree.iterparse("delme.xml", events=('end',), tag="domain"): 
    for name in xp(elem): 
     print(name.text) 

出力:

EDIServices_MS1 
EDIServices_MS2 
EDIServices_MC1 
EDIServices_MC2 

編集:両方のパターンと一致するように、粗XPathを作成しました。