2017-03-18 38 views
1

我想在所有的xml文件中以增量方式將TEXT_VALUE字段的值作爲前綴的前綴,只有名爲「TRANSL」的標籤帶有ID =「示例」。 目前我正在手動做,但由於我有幾千個,我想我應該以編程方式。xml批量文件編輯器按編號遞增

這裏是最初版本:

<TRANSL ID="Example"> 
    <TRANSCIPT> 
     <REF_TEXT TEXT_ID="a680" TXT_TM="a24"> 
      <TEXT_VALUE>this is an example</TEXT_VALUE> 
     </REF_TEXT> 
    </TRANSCIPT> 
    <TRANSCIPT> 
     <REF_TEXT TEXT_ID="a681" TXT_TM="a25"> 
      <TEXT_VALUE>another example</TEXT_VALUE> 
     </REF_TEXT> 
    </TRANSCIPT> 
    <TRANSCIPT> 
     <REF_TEXT TEXT_ID="a682" TXT_TM="a26"> 
      <TEXT_VALUE>third example</TEXT_VALUE> 
     </REF_TEXT> 
    </TRANSCIPT> 
</TRANS> 

這裏是它應該如何看起來像編輯後的版本:

<TRANSL ID="Example"> 
    <TRANSCIPT> 
     <REF_TEXT TEXT_ID="a680" TXT_TM="a24"> 
      <TEXT_VALUE>1-this is an example</TEXT_VALUE> 
     </REF_TEXT> 
    </TRANSCIPT> 
    <TRANSCIPT> 
     <REF_TEXT TEXT_ID="a681" TXT_TM="a25"> 
      <TEXT_VALUE>2-another example</TEXT_VALUE> 
     </REF_TEXT> 
    </TRANSCIPT> 
    <TRANSCIPT> 
     <REF_TEXT TEXT_ID="a682" TXT_TM="a26"> 
      <TEXT_VALUE>3-third example</TEXT_VALUE> 
     </REF_TEXT> 
    </TRANSCIPT> 
</TRANS> 

我怎麼能做到這一點編程?有沒有專業的XML編輯器?如果沒有,我怎麼能在python,powershell,perl,notepad ++,或者其他的,例如?

這裏是我的Python作爲一個記事本+ +插件腳本:

def increment_replace(match): 
    return "<TEXT_VALUE>{}".format(str(int(match.group(1))+1)) 

editor.rereplace(r'\<TEXT_VALUE\>', increment_replace) 

,但它不工作...

回答

3

要獲得當前計數/您可以參閱<TEXT_VALUE>元素position()到父母<TRANSCIPT>元素的count/position()

要通過該計數到後續模板I used the solution from this SO answer和併入其方法在身份模板現在將含有一些值的num參數。 num參數在<for-each>循環中生成,高於所有<TRANSCIPT>元素,並向下傳遞<apply-templates>層級結構以用於TEXT_VALUE模板(其他地方只是被忽略)。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <!-- modified identity template --> 
    <xsl:template match="node()|@*"> 
    <xsl:param name="num" /> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"> 
     <xsl:with-param name="num" select="$num"/> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="TRANSL"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*" /> 
     <xsl:for-each select="TRANSCIPT"> 
     <xsl:copy> 
     <xsl:apply-templates> 
      <xsl:with-param name="num" select="position()" /> 
     </xsl:apply-templates> 
     </xsl:copy> 
     </xsl:for-each>  
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="TEXT_VALUE[../../../@ID='Example']"> <!-- added after extension of question --> 
    <xsl:param name="num" /> 
    <xsl:element name="TEXT_VALUE"> 
     <xsl:value-of select="concat($num,'-',text())" /> 
    </xsl:element>   
    </xsl:template> 

</xsl:stylesheet> 

編輯:
要求後在註釋已擴展我添加謂詞到TEXT_VALUE模板修改所述匹配規則僅選擇具有一個@ID屬性具有值「實施例」 TEXT_VALUE元件。

+0

應該怎麼跑的?我是這個環境的新手......我如何運行這個來替換所有文件中的作業? – cplus

+0

@cplus:您可以使用任何XSLT-1.0處理器執行此作業。哪一個取決於你的操作系統。在任何Linux版本中,您可以使用例如'xsltproc',通常是默認安裝的一部分。但Windows和Mac也有很多其他功能。與操作系統無關的是[Saxon](http://saxon.sourceforge.net/),它是用Java編寫的,同時也支持XSLT-2.0。 – zx485

+0

@cplus:如果您通過_bash腳本_/_批處理file_傳遞文件名,此任務應在一分鐘內完成。 – zx485

2

要使用count(preceding-sibling::*)通過變體XSLT腳本添加到@ zx485,請考慮使用lxml以下Python解決方案。作爲信息,XSLT是用於轉換XML文件的專用語言,它可以成爲一種方便的工具,可以將初始XML文件操作爲最終最終使用格式。

使用Python作爲一個通用languge,你可以利用它的os文件系統模塊和第三方模塊lxml(與XPath 1.0和XSLT 1.0功能的完全兼容W3C庫)以反覆創建所需的輸出。

XSLT(另存爲。XSL文件在Python解析)

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

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

    <!-- Add Incremenet Number to Text --> 
    <xsl:template match="TEXT_VALUE[ancestor::TRANSL/@ID='Example']"> 
    <xsl:copy>  
     <xsl:value-of select="concat(count(ancestor::TRANSCIPT/preceding-sibling::TRANSCIPT)+1, '-', text())"/> 
    </xsl:copy> 
    </xsl:template> 

</xsl:transform> 

的Python

import os 
import lxml.etree as et 

# CHANGE DIRECTORY 
os.chdir('/path/to/raw/XML/files') 

# LOAD XSLT SCRIPT AND INITIALIZE TRANSFORMER 
xslt = et.parse('/path/to/XSLT_Script.xsl') 
transform = et.XSLT(xslt) 

for file in os.listdir(): 
    if file.endswith('.xml'): 

     # LOAD SOURCE XML 
     dom = et.parse(file) 

     # TRANSFORM TO NEW TREE 
     newdom = transform(dom) 

     # SAVE TO FILE (SAME NAME WITH _new SUFFIX) 
     with open(file.replace('.xml', '_new.xml'), 'wb') as f: 
      f.write(newdom)