2017-06-16 20 views
1

私は、特定の色(内部)のセルがある要素のスタイルIDを取得する必要があるExcel XMLファイルを持っています。Python lxmlでExcel xmlの親属性を取得する

私は例として、このExcelのXMLを持っている:

をそしてそれは、文書のヘッダーです:

<?xml version="1.0"?> 
<?mso-application progid="Excel.Sheet"?> 
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:o="urn:schemas-microsoft-com:office:office" 
    xmlns:x="urn:schemas-microsoft-com:office:excel" 
    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:html="http://www.w3.org/TR/REC-html40"> 
    <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"> 

そして、ここで私がアクセスに必要なもの:

<Style ss:ID="s64"> 
    <Interior ss:Color="#00CC00" ss:Pattern="Solid"/> 
</Style> 

私が必要#00CC00という色を渡して、この要素を取得した後、その親にアクセスしてIDを取得する関数を作成します。

このコードで試したところ、有効ではありません。私はネームスペースを使用すると思う。

parser = et.parse(str(file)) 
color = parser.xpath("//interior[@ss:Color='#FFCC00'") 
par = color.getparent() 
print(par) 

コードが "s64"を返す必要があります。

ただし、有効なコードではありません。何が欠けているのですか?

EDIT:私は私の質問を編集し、それが空のリストを返します。しかし、私は、コード

def _find_color(self): 
    """ 
    Find the color in the xml file and returns the attribute. 
    """ 
    print('The folder is: ', self.path) 
    nsd ={'Default':'urn:schemas-microsoft-com:office:spreadsheet', 
       'o': 'urn:schemas-microsoft-com:office:office', 
       'ss': 'urn:schemas-microsoft-com:office:spreadsheet'} 
    if pathlib.Path(self.path).exists(): 
     for file in self.folder.glob('**/*.xml'): 
      print('The file is ', file) 
      parser = et.parse(str(file)) 
      color = parser.xpath("//style/interior[@ss:Color='#00CC00']",namespaces=nsd) 
      print(color) 
      #par = color.getparent() 
      #print(par) 

のこの作品を書いているより多くの情報を探した後、いくつかの余分な情報を追加したいです。それで何も見つかりません。

私はXPathを使用して属性に基づいて要素を見つけることができないのです

<?xml version="1.0"?> 
<?mso-application progid="Excel.Sheet"?> 
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:o="urn:schemas-microsoft-com:office:office" 
    xmlns:x="urn:schemas-microsoft-com:office:excel" 
    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:html="http://www.w3.org/TR/REC-html40"> 
    <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"> 
    <Author>Somebody</Author> 
    <LastAuthor>Somebody</LastAuthor> 
    <Created>2016-05-16T10:44:52Z</Created> 
    <Company>SomeCompany</Company> 
    <Version>12.00</Version> 
    </DocumentProperties> 
    <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel"> 
    <WindowHeight>9495</WindowHeight> 
    <WindowWidth>20835</WindowWidth> 
    <WindowTopX>240</WindowTopX> 
    <WindowTopY>420</WindowTopY> 
    <ProtectStructure>False</ProtectStructure> 
    <ProtectWindows>False</ProtectWindows> 
    </ExcelWorkbook> 
    <Styles> 
    <Style ss:ID="Default" ss:Name="Normal"> 
     <Alignment ss:Vertical="Bottom"/> 
     <Borders/> 
     <Font ss:FontName="Arial" x:Family="Swiss"/> 
     <Interior/> 
     <NumberFormat/> 
     <Protection/> 
    </Style> 
    <Style ss:ID="s63"> 
     <Font ss:FontName="Arial" x:Family="Swiss" ss:Color="#FF0000" ss:Bold="1"/> 
    </Style> 
    <Style ss:ID="s64"> 
     <Interior ss:Color="#00CC00" ss:Pattern="Solid"/> 
    </Style> 
    <Style ss:ID="s65"> 
     <Font ss:FontName="Arial" x:Family="Swiss" ss:Color="#FF0000" ss:Bold="1"/> 
    <Interior ss:Color="#44CF00" ss:Pattern="Solid"/> 
     </Style> 
    </Styles> 

で動作するように興味を持っています全体のソース部分を追加します。

答えて

1

これはどのように行うことができます。

from lxml import etree as ET 

NS = {"ss": "urn:schemas-microsoft-com:office:spreadsheet"} 

tree = ET.parse("workbook.xml") 
interior = tree.find("//ss:Style/ss:Interior[@ss:Color='#00CC00']", namespaces=NS) 
print(interior.getparent().get("{urn:schemas-microsoft-com:office:spreadsheet}ID")) 

出力:

s64 

コメント:

  • ssプレフィックスは、すべての要素を使用する必要があります。
  • XMLは大文字と小文字を区別します(Style!= style)。
  • 名前空間の値がIDの場合、URI(プレフィックスではない)を使用する必要があります。
+0

動作しません。私はNoneオブジェクトを取得します。私はそれが本当に木を作っていないからだと思う。 getroot()を追加し、findで生成されたオブジェクトを使用すると、要素の絶対パスを使用できないというエラーが表示されます。 また、使用する名前空間のみを使用して辞書を作成できますか?この場合は「ss」を使用します。 – TMikonos

+0

私は何を追加できるか分かりません。コードは私のために働く。 'getroot()'を追加する必要はありません。私の答えの中の "workbook.xml"は、あなたのXMLを質問から整理して整形するために追加された ''というタグで始まります。そして、はい、NS辞書は、実際にコードで使用されている名前空間だけを含める必要があります。 – mzjn

0

私が最終的に解決策を見つけました。 過ちの1つは、私は(私は(getrootでこれを解決し))ツリーを生成していなかったということだったように見えます だから私のソリューションです:

def _find_color(self): 
    """ 
    Find the color in the xml file and returns the attribute. 
    """ 
    print('The folder is: ', self.path) 
    nsd ={'Default':'urn:schemas-microsoft-com:office:spreadsheet', 
       'o': 'urn:schemas-microsoft-com:office:office', 
       'ss': 'urn:schemas-microsoft-com:office:spreadsheet'} 
    if pathlib.Path(self.path).exists(): 
     for file in self.folder.glob('**/*.xml'): 
      print('The file is ', file) 
      parser = et.parse(str(file)) 
      root=parser.getroot() 
      color = root.xpath("//Default:Interior[@ss:Color='#FFCC00']",namespaces=nsd) 
    print(color) 
      for element in color: 
       print('Tag: ', element.tag, 'Attribute: ', element.attrib) 
       par_id= element.getparent().get("{urn:schemas-microsoft-com:office:spreadsheet}ID") 
       print(par_id) 

それはS64を返します。

親のIDを取得する部分については、私はmzjnが私に提供した解決策を使用しました。私は、短い名前の代わりにURIを使用しなければならないことを知っていました。

関連する問題