2017-05-03 9 views
0

私は、特定のタグの値を変更するためにlxmlを使用するpythonスクリプトを持っています。しかし私は、すべての3のためのタグが同じで、私は特定の日付に日付を変更する各異なる日付タイプ(出版、作成と改訂)については、次のXML同じタグを持つ複数の場所のxml値を変更する

    <gmd:CI_Citation> 
        <gmd:date> 
         <gmd:CI_Date> 
          <gmd:date> 
           <gco:Date>**1900-01-01**</gco:Date> 
          </gmd:date> 
          <gmd:dateType> 
           <gmd:CI_DateTypeCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="publication">Publication</gmd:CI_DateTypeCode> 
          </gmd:dateType> 
         </gmd:CI_Date> 
        </gmd:date> 
        <gmd:date> 
         <gmd:CI_Date> 
          <gmd:date> 
           <gco:Date>**1900-01-01**</gco:Date> 
          </gmd:date> 
          <gmd:dateType> 
           <gmd:CI_DateTypeCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="creation">Creation</gmd:CI_DateTypeCode> 
          </gmd:dateType> 
         </gmd:CI_Date> 
        </gmd:date> 
        <gmd:date> 
         <gmd:CI_Date> 
          <gmd:date> 
           <gco:Date>**1900-01-01**</gco:Date> 
          </gmd:date> 
          <gmd:dateType> 
           <gmd:CI_DateTypeCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="revision">Revision</gmd:CI_DateTypeCode> 
          </gmd:dateType> 
         </gmd:CI_Date> 
        </gmd:date> 
       </gmd:CI_Citation> 

を持っている -

//:gmd_citation/:gmd_CI:Citation/:gmd_date/:gmd_CI_Date/:gmd_date/:gco_Date 
私は値を変更するには、次の機能を使用しています

def updateXMLTag (tag, value): 
    xmlValue = root.xpath(tag) 
    xmlValue[0].text = str(value) 

何特定のタグに到達するためにxpathを使用する最善の方法ですので、値を変更することができますか?

+3

XML入力は、 'gmd'と' gco' pr efixesは宣言されていません。 – mzjn

+0

これはxmlの仕組みです。 (私はXML文書の一部のみを投稿していますが)。 – MapMan

+2

私は何度もXMLの質問にコメントしました。名前空間を持つXML(コロンで区切られた接頭辞)は常にルートタグを含み、名前空間URIが定義されているところでは(xmlns = 'を検索します)。サンプル投稿を更新してください。 – Parfait

答えて

1

これは、特定の要素を取得し、それらを編集するためにXPathを使用しての私の方法です:

# Find the best implementation available on the platform 

try: 
    from cStringIO import StringIO 
except: 
    from StringIO import StringIO 

from lxml import etree 

# proper namespaces added to get valid xml 
xmlstr = StringIO("""<gmd:CI_Citation xmlns:gmd="http://gmd.example.com" xmlns:gco="http://gco.example.com"> 
     <gmd:date> 
     <gmd:CI_Date> 
      <gmd:date> 
       <gco:Date>1900-01-01</gco:Date> 
      </gmd:date> 
      <gmd:dateType> 
       <gmd:CI_DateTypeCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="publication">Publication</gmd:CI_DateTypeCode> 
      </gmd:dateType> 
     </gmd:CI_Date> 
    </gmd:date> 
    <gmd:date> 
     <gmd:CI_Date> 
      <gmd:date> 
       <gco:Date>1900-01-01</gco:Date> 
      </gmd:date> 
      <gmd:dateType> 
       <gmd:CI_DateTypeCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="creation">Creation</gmd:CI_DateTypeCode> 
      </gmd:dateType> 
     </gmd:CI_Date> 
    </gmd:date> 
    <gmd:date> 
     <gmd:CI_Date> 
      <gmd:date> 
       <gco:Date>1900-01-01</gco:Date> 
      </gmd:date> 
     <gmd:dateType> 
      <gmd:CI_DateTypeCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="revision">Revision</gmd:CI_DateTypeCode> 
      </gmd:dateType> 
     </gmd:CI_Date> 
    </gmd:date> 
</gmd:CI_Citation>""") 

tree = etree.parse(xmlstr) 

ここでは、我々はすべての(3)ターゲット要素を取得するためにXPathを使用しています。 "出版"/"公開":単純な関数でhasattr

def hasattr(elem, att, val): 
    try: 
     return elem.attrib[att] == val 
    except: 
     return False 

ターゲット[0] codeListValue /テキストノードを確認することができ

targets = tree.xpath('/gmd:CI_Citation/gmd:date/gmd:CI_Date/gmd:dateType/gmd:CI_DateTypeCode', \ 
      namespaces={'gmd': "http://gmd.example.com", 'gco': "http://gco.example.com"}) 

三つの要素は、固有の属性値によって区別され、

ターゲット[1] codeListValue /テキストノード: "作成"/"作成"

ターゲット[2] codeListValue /テキストノード:「リビジョン」/「リビジョン」

変更する必要があるのはどれですか?

hasattr(targets[0], 'codeListValue', 'publication') # True 
hasattr(targets[1], 'codeListValue', 'creation') # True 
hasattr(targets[2], 'codeListValue', 'publication') # False 

# Let's change one of them 
t1 = targets[1] 
t1.text = 'New Creation' # change text node 

# and/or change attribute 
t1.attrib['codeListValue'] = 'Latest Creation' 

最後に、我々は我々が(GCO:日)cousin1に移動し、ファイル

tree.write("output1.xml") 

編集ここ1

に結果を保存し、すでにのは、ターゲットを発見した[1]そのニーズが変更されました:

t1 = targets[1] 
parent1 = t1.getparent() 
date1 = parent1.getprevious() 
cousin1 = date1.getchildren() 
len(cousin1)  #1 
cousin1[0].text #'1900-01-01' 

# change the date 
cousin1[0].text = '2017-5-3' 
# again, write the result 

tree.write("out456.xml") 
+0

この例ではありがたいですが、gco:Dateは変更されません。これはcodeListvalueのテキストではなく変更する必要があるものです。 – MapMan

+1

@MapMan、私は日付を変更する方法を示す私の答えを編集しました。 – swatchai

関連する問題