
까다로운 문제가 있습니다. 많은 수의 XML 파일(500개 이상)을 약간 변경해야 합니다. 변경에는 값을 'false'에서 'true'로 전환하는 작업이 포함됩니다. 변경해야 할 줄은 다음과 같습니다.
<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는 문자와 일치하지만 일치를 포기하고 결과(일치 또는 일치 없음)만 반환합니다.
여기에서 자세한 내용을 확인할 수 있습니다. Lookahead 및 Lookbehind 길이가 0인 어설션
답변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>