1

У меня есть каверзная проблема. Мне нужно внести небольшие изменения в большое количество 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.АВТОБУС.Линия ДКВ в качестве отправной точки. По сути, мне нужно изменить первое вхождение строки SizeisMeasured, которая приходит непосредственно ПОСЛЕ CID.АВТОБУС.Линия ДКВ. Но между ними есть много других строк (ни одна из которых не является последовательной от файла к файлу), которые меня не волнуют, и они запутывают мой поиск.

2 ответа2

1

Вы можете использовать отрицательный взгляд, как это. Поиск

(?!<CID>.*BUS..*.DKV</CID>(.*?))<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>

и заменить на

<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>

Регулярное выражение, соответствие. новая линия

Отрицательный Lookahead (?!a) и отрицательный взгляд сзади (?<!a) , также упоминаются как Lookaround. Lookaround сопоставляет символы, но затем бросает совпадение, возвращая только результат: совпадение или отсутствие совпадения.

Вы можете найти больше здесь Lookahead и Lookbehind Утверждения нулевой длины

0

Разбор XML при соблюдении иерархии с помощью регулярных выражений неоправданно затруднен. Я бы использовал совершенно другой инструмент, который явно предназначен для того, что вы пытаетесь сделать, - преобразование XML. Я говорю о XSLT. Итак, вот мое решение вашей проблемы с использованием XSLT. Существует целый ряд веб-сайтов, которые вы можете использовать для преобразования вашего XML с помощью XSLT или же вы можете запустить XSLT локально.

Проблема была бы проще, если бы каждая из ваших групп (CID, а затем SizeIsMeasuredLineLine) находилась в пределах одного родителя, но код ниже просматривает первого предшествующего брата CID, чтобы увидеть, какое значение оно имеет. Если оно имеет значение, соответствующее регулярному выражению (ITEMNAME. [^.]+.ITEMNAME ..+) затем он изменяет ложь на истину. Все остальные элементы просто копируются на выход.

<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>

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .