Добавьте/удалите теги XML с помощью сценария удара

У меня есть XML-файл, что я хочу настроить использование сценария удара. Например, если у меня был этот xml:

<a>

  <b>
    <bb>
        <yyy>
            Bla 
        </yyy>
    </bb>
  </b>

  <c>
    <cc>
      Something
    </cc>
  </c>

  <d>
    bla
  </d>
</a>

(конфиденциальная информация удалила),

Я хотел бы записать сценарий удара, который удалит раздел <b> (или прокомментируйте это), но сохраните остальную часть xml неповрежденного. Я довольно новый целая вещь сценариев. Я задавался вопросом, мог ли кто-либо дать мне подсказку относительно того, что я должен изучить.

Я думал, что sed мог использоваться кроме sed, строчный редактор. Я думаю, что было бы легко удалить <b> теги однако, я не уверен, если sed смог бы удалить весь текст между <b> теги.

Я должен буду также записать сценарий для добавления назад удаленного раздела.

21
задан sixtyfootersdude 1 April 2010 в 05:27
поделиться

6 ответов

Это не составит труда сделать в sed, поскольку sed также работает с диапазонами.

Попробуйте это (при условии, что xml находится в файле с именем foo.xml):

sed -i '/<b>/,/<\/b>/d' foo.xml

-i запишет изменение в исходный файл (используйте -i.bak, чтобы сохранить резервную копию оригинала)

Эта команда sed выполнит действие d (удалить) во всех строках заданный диапазоном

# all of the lines between a line that matches <b>
# and the next line that matches <\/b>, inclusive
/<b>/,/<\/b>/

Таким образом, на простом английском языке эта команда удалит все строки между строкой с и строкой с

включительно. Если вы предпочитаете закомментировать строки попробуйте один из следующих вариантов:

# block comment
sed -i 's/<b>/<!-- <b>/; s/<\/b>/<\/b> -->/' foo.xml

# comment out every line in the range
sed -i '/<b>/,/<\/b>/s/.*/<!-- & -->/' foo.xml
24
ответ дан 16 October 2019 в 23:39
поделиться

Если вам нужна наиболее подходящая замена для sed для данных XML, то это будет процессор XSLT. Как и sed , это сложный язык, но он специализируется на задачах преобразования XML во что-либо.

С другой стороны, это действительно кажется точкой, в которой я бы серьезно подумал о переходе на настоящий язык программирования, такой как Python.

6
ответ дан 16 October 2019 в 23:39
поделиться

Вы можете использовать XSLT, подобный этому, который является преобразованием модифицированной идентичности. Он копирует все содержимое по умолчанию и имеет пустой шаблон для b , который ничего не делает (фактически удаляет из вывода):

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

<!--Identity transform copies all items by default -->
<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!--Empty template to match on b elements and prevent it from being copied to output -->
<xsl:template match="b"/>

</xsl:stylesheet>

Создайте сценарий bash, который выполняет преобразование с использованием Java и Утилита командной строки Xalan выглядит так:

java org.apache.xalan.xslt.Process -IN foo.xml -XSL foo.xsl -OUT foo.out

Результат следующий:

<?xml version="1.0" encoding="UTF-16"?><a><c><cc>
      Something
    </cc></c><d>
    bla
  </d></a>

РЕДАКТИРОВАТЬ: , если вы предпочитаете, чтобы b закомментировали, чтобы упростить возврат, используйте эту таблицу стилей:

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

    <!--Identity transform copies all items by default -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!--Match on b element, wrap in a comment and construct text representing XML structure by applying templates in "comment" mode -->
    <xsl:template match="b">
        <xsl:comment>
            <xsl:apply-templates select="self::*" mode="comment" />
        </xsl:comment>
    </xsl:template>

    <xsl:template match="*" mode="comment">
        <xsl:value-of select="'&lt;'"/>
            <xsl:value-of select="name()"/>
        <xsl:value-of select="'&gt;'"/>
            <xsl:apply-templates select="@*|node()" mode="comment" />
        <xsl:value-of select="'&lt;/'"/>
            <xsl:value-of select="name()"/>
        <xsl:value-of select="'&gt;'"/>
    </xsl:template>

    <xsl:template match="text()" mode="comment">
        <xsl:value-of select="."/>
    </xsl:template>

    <xsl:template match="@*" mode="comment">
        <xsl:value-of select="name()"/>
        <xsl:text>="</xsl:text>
        <xsl:value-of select="."/>
        <xsl:text>" </xsl:text>
    </xsl:template>

</xsl:stylesheet>

Результат будет следующим:

<?xml version="1.0" encoding="UTF-16"?><a><!--<b><bb><yyy>
            Bla
        </yyy></bb></b>--><c><cc>
      Something
    </cc></c><d>
    bla
  </d></a>
9
ответ дан 16 October 2019 в 23:39
поделиться

@OP, вы можете использовать awk, например,

$ cat file
<a>                              

some text before   <b>
    <bb>
        <yyy>
            Bla
        </yyy>
    </bb>
  </b> some text after

  <c>
    <cc>
      Something
    </cc>
  </c>

  <d>
    bla
  </d>
</a>

$ awk 'BEGIN{RS="</b>"}/<b>/{gsub(/<b>.*/,"")}1' file
<a>

some text before
 some text after

  <c>
    <cc>
      Something
    </cc>
  </c>

  <d>
    bla
  </d>
</a>
3
ответ дан 16 October 2019 в 23:39
поделиться

Использование xmlstarlet:

#xmlstarlet ed -d "/a/b" file.xml > tmp.xml
xmlstarlet ed -d "//b" file.xml > tmp.xml
mv tmp.xml file.xml
14
ответ дан 16 October 2019 в 23:39
поделиться
# edit file inplace
xmlstarlet ed -L -d "//b" file.xml
3
ответ дан 16 October 2019 в 23:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: