
我有一個棘手的問題。我需要對大量 xml 檔案(500+)進行微小的更改。該更改涉及將值從“假”切換為“真”。需要更改的行如下所示:
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
它需要變成:
<SizeIsMeasuredLineLine>true</SizeIsMeasuredLineLine>
不幸的是,每個檔案中都有許多這組標籤的實例,因此我們無法進行簡單的尋找和取代。這組標籤的獨特之處在於它們位於以下幾行之後:
<CID>ITEMNAME.BUS.ITEMNAME.DKV</CID>
但是,每個文件都有不同的項目名稱,因此我使用通配符將其過濾掉。
<CID>.*BUS..*.DKV</CID>
問題是,CID 部分和需要更改的行之間的行數在每個文件中並不一致。我需要找到一種方法來通配符之間的行,並替換“大小”行。
有任何想法嗎?我已經嘗試過:
<CID>.*BUS..*.DKV</CID>.*?<SizeIsMeasuredLineLine>true</SizeIsMeasuredLineLine>
但由於某種原因,這不起作用。先感謝您!
編輯回覆評論:
基本上我想說的是程式碼如下圖:
<CID>ITEMNAME.BUS.ITEMNAME.DKV</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
程式碼中的其他部分如下所示:
<CID>ITEMNAME.COLR.ITEMNAME.FCLR</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
在代碼的其他地方。所以我使用 CID .BUS .DKV 線作為起點。基本上,我需要更改直接在 CID .BUS .DKV 行之後出現的 SizeisMeasured 行的第一次出現。但中間還有很多其他行(文件與文件之間沒有一致),我不關心這些行,並且弄亂了我的搜索。
答案1
您可以像這樣使用負前瞻。搜尋
(?!<CID>.*BUS..*.DKV</CID>(.*?))<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
並替換為
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
正規表示式,匹配。新隊
Negative Lookahead(?!a)
和 Negative Lookbehind(?<!a)
也稱為 Lookaround。 Lookaround 匹配字符,但隨後放棄匹配,僅返回結果:匹配或不匹配。
您可以在這裡找到更多信息 前向和後向零長度斷言
答案2
在使用正規表示式尊重層次結構的同時解析 XML 是不必要的困難。我會使用一個完全不同的工具,它是專門為您想要做的事情而設計的,即轉換 XML。我說的是 XSLT。因此,這是我使用 XSLT 解決您的問題的解決方案。有許多網站可供您使用 XSLT 轉換 XML,或者您也可以在本機上執行 XSLT。
如果每個群組(CID 後面跟著 SizeIsMeasuredLineLine)都在單一父級中,那麼問題會更容易,但下面的程式碼會查看第一個前面的 CID 同級以查看它具有什麼值。如果它的值與正規表示式 (ITEMNAME.[^.]+.ITEMNAME..+) 匹配,則它將 false 更改為 true。所有其他元素都簡單地複製到輸出。
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SizeIsMeasuredLineLine[matches(preceding-sibling::CID[1], 'ITEMNAME\.[^.]+\.ITEMNAME\..+')]">
<xsl:copy>TRUE</xsl:copy>
</xsl:template>
以下是我為測試上述內容而建立的範例 XML:
<?xml version="1.0" encoding="UTF-8"?>
<parent>
<CID>ITEMNAME.BUS.ITEMNAME.DKV</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.COLR.ITEMNAME.FCLR</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.BUS.122.DKV</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.COLR.ITEMNAME.FCLR</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.BUS.44.DKV</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.COLR.ITEMNAME.FCLR</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.BUS.33.DKV</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.COLR.ITEMNAME.FCLR</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
</parent>