2016-11-09 18 views
0

私はPythonで編集しているXML文書全体を持っています。これは毎月生成され、手で編集されたドキュメントで、少なくともそのプロセスの一部を自動化しようとしています。これの最初の部分は正常です。しかし、XSLTドキュメント(change())を使って最終的な並べ替えを行ってドキュメントを実行すると、並べ替えられた要素と元の要素が元の順序で取得されますが、理由はわかりません。同じファイルを繰り返し書き直していたからだと思っていましたが、change()が実行されるまで重複は表示されません。だから私はそれがXSLTの使い方とは何かを前提にしていますが、私はそれを実際に初心者にしています。だから私を撃ちたいと思ったらどんな助けでも大歓迎です。XMLをXSLTシートに渡すとノードが重複します

from __future__ import print_function 

from lxml import etree 
import xml.etree.ElementTree as et  

def adultSmash(): 
     def adultGrab(): #grab all adult events 
         src_tree = et.parse('quartertwo.xml') 
         src_root = src_tree.getroot() 
         dest_tree = et.parse('dest_tree.xml') 
         dest_root = dest_tree.getroot() 
         for event in src_root.findall('event'): 
             agerange = event.find('AgeRanges') 
             if agerange is None: 
                 continue 
             ageranges = agerange.text 
             if ageranges == 'Adult': 
                 dest_root.append(event) 
         et.ElementTree(dest_root).write('dest_tree.xml') 

     def clean(): 
         dest_tree = et.parse('dest_tree.xml') 
         dest_root = dest_tree.getroot() 
         for event in dest_root.findall('event'): 
           book = event.find('EventType') # 
           books = book.text 
           if books == 'Book Groups': 
             dest_root.remove(event) 
           elif books == 'Book Sales': 
             dest_root.remove(event) 
           elif books == 'Bookmobile Stop': 
             dest_root.remove(event) 
         et.ElementTree(dest_root).write('dest_tree.xml') 

     def cleanNodes(): 
         dest_tree = et.parse('dest_tree.xml') 
         dest_root = dest_tree.getroot() 

         foos = dest_tree.findall('event') 
         for event in foos: 
           bars = event.findall('Notes') 
           for Notes in bars: 
             event.remove(Notes) 
         et.ElementTree(dest_root).write('dest_tree.xml') 

     def change():    
       dom = et.parse('dest_tree.xml') 
       xslt = et.parse('change.xslt') 
       transform = et.XSLT(xslt) 
       newdom = transform(dom) 
       log = open('dest_tree.xml', 'w') 
       print(str(newdom), file = log) 
    adultGrab() 
    clean() 
    cleanNodes() 
    change() 

これはこれは私がそれを変更するために使用しているXSLTでXML

<?xml version="1.0" encoding="utf-8"?> 
<events> 
    <event> 
    <EventType>Blah</EventType> 
    <title>Blah Blah</title> 
    <RelatedLocations>Blah</RelatedLocations> 
    <Date>Friday, September 2, 2016</Date> 
    <DateYear>2016</DateYear> 
    <DateMonth>09</DateMonth> 
    <DateDay>02</DateDay> 
    <Body>Derp</Body> 
    <Notes>Notes are not displayed to the public.</Notes> 
    </event> 
    <event> 
    <EventType>Blah</EventType> 
    <title>Blah Blah</title> 
    <RelatedLocations>Blah</RelatedLocations> 
    <Date>Friday, September 2, 2016</Date> 
    <DateYear>2016</DateYear> 
    <DateMonth>09</DateMonth> 
    <DateDay>02</DateDay> 
    <Body>Derp</Body> 
    <Notes>Notes are not displayed to the public.</Notes> 
    </event> 
</events> 

です:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output encoding="UTF-8" indent="yes" method="xml" /> 
    <xsl:strip-space elements="*"/> 
    <xsl:template match="node()|@*"> 
      <xsl:copy> 
        <xsl:apply-templates select="node()|@*"/> 
      </xsl:copy> 
    </xsl:template> 
    <xsl:template match="event"> 
      <xsl:copy> 
        <xsl:apply-templates select="@*" /> 
        <xsl:apply-templates select="title" /> 
        <xsl:apply-templates select="RelatedLocations" /> 
        <xsl:apply-templates select="Date" /> 
        <xsl:apply-templates select="DateYear" /> 
        <xsl:apply-templates select="DateMonth" /> 
        <xsl:apply-templates select="DateDay" /> 
        <xsl:apply-templates select="Body" /> 
        <xsl:apply-templates select="AgeRanges" /> 
        <xsl:apply-templates select="*[not(self::Location or self::EventType)]" /> 
      </xsl:copy> 
    </xsl:template> 

、最終的にはこれが結果です:

<?xml version="1.0" encoding="UTF-8"?> 
<events> 
    <event> 
    <title>Blah</title> 
    <RelatedLocations>Derp</RelatedLocations> 
    <Date>Every Saturday through Nov 30 2016. Saturday, October 1, 2016 - 10 a.m.-5 p.m.</Date> 
    <DateYear>2016</DateYear> 
    <DateMonth>10</DateMonth> 
    <DateDay>01</DateDay> 
<Body>Blah</Body> 
<AgeRanges>Adult</AgeRanges> 
<AgeRanges>Adult</AgeRanges> 
<title></title> 
<RelatedLocations>Blah</RelatedLocations> 
<Date>Every Saturday through Nov 30 2016. Saturday, October 1, 2016 - 10 a.m.-5 p.m.</Date> 
<DateYear>2016</DateYear> 
<DateMonth>10</DateMonth> 
<DateDay>01</DateDay> 
<Body>Blah</Body> 

ですから、どんな助力にも感謝します。

+0

あなたはどのような結果を期待していますか? –

答えて

0

同じノードにテンプレートを2回適用しているため、出力に重複ノードが発生しています。たとえば、あなたが実行します。

<xsl:apply-templates select="title" /> 

、その後:

<xsl:apply-templates select="*[not(self::Location or self::EventType)]" /> 

title要素はLocationEventTypeでもないので、第2の命令が再びそれにテンプレートを適用します。

+0

これは本当にありがとうございました! –

関連する問題