2016-06-07 9 views
0

Ich bin ratlos auf der Suche nach einer Möglichkeit zum Suchen und Ersetzen von Zeichen basierend auf der Position. Im Grunde, was ich suche es in ein Dokument gehen zu tun undSuchen und Ersetzen in Python - basierend auf unbekannten Zeichen

<gco:DateTime>2016-04-20T11:27:34.8677919-06:00</gco:DateTime> 

Mit

<gco:DateTime>2016-04-20T11:27:34</gco:DateTime> 

Alles ersetzen, nachdem das Dezimalzeichen muss gelöscht werden. Das Problem ist, dass dies für mehrere Zeitstempel in XML-Dateien gilt und jeder dieser Zeitstempel völlig anders ist. Ich habe ein wenig über Regex gelesen und es scheint eine mögliche Methode zu sein. Jede Hilfe würde sehr geschätzt werden.

bearbeiten Beispiel für XML-Dateiformat:

<?xml version="1.0" encoding="utf-8"?> 
<?xml-stylesheet type='text/xsl' href='http://ngis/ngis/metadata/StyleSheet/xslt/nGIS_Metadata.xslt'?> 
<gmd:MD_Metadata xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gmx="http://www.isotc211.org/2005/gmx" xmlns:gts="http://www.isotc211.org/2005/gts" xmlns:gfc="http://www.isotc211.org/2005/gfc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gss="http://www.isotc211.org/2005/gss" xmlns:gsr="http://www.isotc211.org/2005/gsr" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gmi="http://www.isotc211.org/2005/gmi" xmlns:gmd="http://www.isotc211.org/2005/gmd"> 
    <gmd:fileIdentifier> 
     <gco:CharacterString>BF244A7CB62491BC74B001BE5DEAA213AAFB9DBA</gco:CharacterString> 
    </gmd:fileIdentifier> 
    <gmd:language> 
     <gco:CharacterString>English</gco:CharacterString> 
       <gmd:date> 
       <gco:DateTime>2016-04-20T11:27:34.8677919-06:00</gco:DateTime> 
       </gmd:date> 

@Parfait

+0

Regexes lösen dieses und andere ähnliche Probleme und Sie sollten weiterlesen. In diesem speziellen Fall ist auch das Analysieren und Formatieren von Daten ein guter Ansatz. –

+0

Ich würde Sie außerdem davor warnen, XML viel zu verarbeiten, ohne es tatsächlich in eine richtige Struktur zu zerlegen, indem Sie eine Bibliothek wie 'lxml' oder' ElementTree' verwenden, obwohl Sie vielleicht davonkommen, wenn alle Ihre Transformationen so unkompliziert sind. – holdenweb

+0

Es kann nicht genug betont werden (vielleicht die am höchsten gewählte Antwort auf SO), [regex html/xml files] (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-) in sich geschlossene Tags). – Parfait

Antwort

0

Betrachten XSLT (die Spezial-deklarative Sprache entwickelt, um XML-Dokumente zu umwandeln), die eine sehr komfortable Funktion hat (gemeinsam mit seinen Geschwistern, XPath) für Ihre Bedürfnisse substring-before() wo Sie die Daten vor der Periode abgrenzt den Zeitstempel zu extrahieren. Pythons Modul lxml kann XSLT 1.0-Skripts ausführen.

Das folgende Skript analysiert XML und XSLT aus der Datei. Insbesondere führt die XSLT die Identitätstransformation aus, um das Dokument so zu kopieren, wie es ist, und extrahiert dann die Zeit von alle<gco:DateTime>. Beachten Sie, dass nur die benötigten gco Namespace im XSLT-Header definiert:

XSLT Script (speichern als extern als XSL-Datei in Python referenziert werden)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
       xmlns:gco="http://www.isotc211.org/2005/gco"> 
<xsl:output version="1.0" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*"/> 

    <!-- Identity Transform --> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="gco:DateTime"> 
    <xsl:copy> 
     <xsl:copy-of select="substring-before(., '.')"/>     
    </xsl:copy> 
    </xsl:template> 

</xsl:transform> 

Python Script

import lxml.etree as ET 

# LOAD XML AND XSL 
dom = ET.parse('Input.xml') 
xslt = ET.parse('XSLTScript.xsl') 

# TRANSFORM XML 
transform = ET.XSLT(xslt) 
newdom = transform(dom) 

# CONVERT TO STRING 
tree_out = ET.tostring(newdom, encoding='UTF-8', pretty_print=True, xml_declaration=True) 

# OUTPUT TREE TO FILE 
xmlfile = open('Output.xml') 
xmlfile.write(tree_out) 
xmlfile.close() 

Ausgabe

<?xml version="1.0"?> 
<?xml-stylesheet type='text/xsl' href='http://ngis/ngis/metadata/StyleSheet/xslt/nGIS_Metadata.xslt'?><gmd:MD_Metadata xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gmx="http://www.isotc211.org/2005/gmx" xmlns:gts="http://www.isotc211.org/2005/gts" xmlns:gfc="http://www.isotc211.org/2005/gfc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gss="http://www.isotc211.org/2005/gss" xmlns:gsr="http://www.isotc211.org/2005/gsr" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gmi="http://www.isotc211.org/2005/gmi" xmlns:gmd="http://www.isotc211.org/2005/gmd"> 
    <gmd:fileIdentifier> 
    <gco:CharacterString>BF244A7CB62491BC74B001BE5DEAA213AAFB9DBA</gco:CharacterString> 
    </gmd:fileIdentifier> 
    <gmd:language> 
    <gco:CharacterString>English</gco:CharacterString> 
    <gmd:date> 
     <gco:DateTime>2016-04-20T11:27:34</gco:DateTime> 
    </gmd:date> 
    </gmd:language> 
</gmd:MD_Metadata> 
+0

Dank Parfait, das funktioniert gut. Schätze es wirklich! – MapZombie

+0

Meine Dateien beginnen alle mit MapZombie

+0

Bitte senden Sie ein Snippet der aktuellen XML-Datei (alle Header, da Sie einen Namensraum haben, 'gco', der definiert werden sollte). Und Sie sollten nicht von der dritten Linie aus starten müssen. – Parfait

0

One way:

s = "<gco:DateTime>2016-04-20T11:27:34.8677919-06:00</gco:DateTime>" 
split_on_dot = s.split('.') 
split_on_angle = split_on_dot[1].split('<') 
new_s = "".join([split_on_dot[0], "<", split_on_angle[1]]) 

>>> new_s 
'<gco:DateTime>2016-04-20T11:27:34</gco:DateTime>' 
>>> 

Dies ist abhängig von der Zeit die einzige Zeit in der Zeichenfolge eingegeben wird. Ich bin nicht so gut in Regexes. Ich denke, sie werden überstrapaziert, aber ich bin sicher, dass jemand dir zeigen wird, wie man Regex benutzt. Denken Sie daran, dass Python native Stringmanipulationen hat.

+0

Danke Joel, ich würde dies benötigen, um mehrere unbekannte Daten für jede Datei analysieren zu können. Es gibt ungefähr 6 Datumsstempel mit diesem Format in jeder Datei.Und das Format ist konsistent durch jedes, wobei nur eine Periode verwendet wird. – MapZombie

+0

Dann, gut, aber beachtet @holdenweb Kommentare über XML-Parsing. Meine Antwort kümmert sich nur um Dinge, sobald Sie das Element haben, das Sie ändern möchten. Stephen Holden stellte mich Python in einem Kurs vor, den er unterrichtete –