
難しい問題があります。多数の XML ファイル (500 以上) に小さな変更を加える必要があります。変更には、値を 'false' から 'true' に切り替えることが含まれます。変更する必要がある行は次のようになります。
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
そして、次のようになる必要があります。
<SizeIsMeasuredLineLine>true</SizeIsMeasuredLineLine>
残念ながら、各ファイルにはこのタグ セットのインスタンスが多数存在するため、単純な検索と置換を行うことはできません。このタグ セットが独特なのは、次の行の後に続く点です。
<CID>ITEMNAME.BUS.ITEMNAME.DKV</CID>
ただし、各ファイルの項目名は異なるため、ワイルドカードを使用して除外していました。
<CID>.*BUS..*.DKV</CID>
問題は、CID 部分と変更が必要な行の間にある行数がファイルごとに一貫していないことです。その間の行をワイルドカードで除外し、Size 行を置き換える方法を見つける必要があります。
何かアイデアはありますか? すでに試しました:
<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>
正規表現、一致する。改行
否定先読み(?!a)
と否定後読みは(?<!a)
、Lookaround とも呼ばれます。Lookaround は文字を一致させますが、一致を放棄し、一致または不一致の結果のみを返します。
詳細はこちら 先読みと後読みのゼロ長アサーション
答え2
正規表現を使用して階層構造を尊重しながら XML を解析するのは、不必要に困難です。XML を変換するという、あなたがしようとしていること専用に設計されたまったく別のツールを使用します。ここで取り上げるのは XSLT です。そこで、XSLT を使用した問題に対する私の解決策を紹介します。XML を XSLT で変換するために使用できる Web サイトは数多くあります。または、XSLT をローカルで実行することもできます。
各グループ (CID の後に SizeIsMeasuredLineLine が続く) が 1 つの親内にある場合は、問題はより簡単になりますが、以下のコードでは、最初の先行 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>