Как удалить элементы из XML с помощью xslt с таблицей стилей и xsltproc? - PullRequest
65 голосов
/ 26 ноября 2008

У меня много XML-файлов, которые имеют вид:

<Element fruit="apple" animal="cat" />

Который я хочу удалить из файла.

Как я могу это сделать с помощью таблицы стилей XSLT и утилиты командной строки Linux xsltproc?

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

<ч />

РЕДАКТИРОВАТЬ: вопрос изначально отсутствовал в намерении.

То, чего я пытаюсь добиться, это удалить весь элемент "Элемент", где (fruit == "apple" && animal == "cat"). В том же документе есть много элементов с именем «Элемент», я хочу, чтобы они остались. Так

<Element fruit="orange" animal="dog" />
<Element fruit="apple"  animal="cat" />
<Element fruit="pear"   animal="wild three eyed mongoose of kentucky" />

станет:

<Element fruit="orange" animal="dog" />
<Element fruit="pear"   animal="wild three eyed mongoose of kentucky" />

Ответы [ 2 ]

127 голосов
/ 26 ноября 2008

Используя один из самых фундаментальных шаблонов проектирования XSLT: «Переопределение преобразования идентификаторов », достаточно написать следующее:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:output omit-xml-declaration="yes"/>

    <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="Element[@fruit='apple' and @animal='cat']"/>
</xsl:stylesheet>

Обратите внимание , как второй шаблон переопределяет шаблон идентификатора (1-й) только для элементов с именем «Элемент», которые имеют атрибут «фрукты» со значением «яблоко» и атрибут «животное» со значением «кошка» ». Этот шаблон имеет пустое тело, что означает, что сопоставляемый элемент просто игнорируется (при сопоставлении ничего не создается).

Когда это преобразование применяется к следующему исходному документу XML:

<doc>... 
    <Element name="same">foo</Element>...
    <Element fruit="apple" animal="cat" />
    <Element fruit="pear" animal="cat" />
    <Element name="same">baz</Element>...
    <Element name="same">foobar</Element>...
</doc>

желаемый результат выдается:

<doc>... 
    <Element name="same">foo</Element>...
    <Element fruit="pear" animal="cat"/>
    <Element name="same">baz</Element>...
    <Element name="same">foobar</Element>...
</doc>

Дополнительные фрагменты кода использования и переопределения шаблона идентификации можно найти здесь .

0 голосов
/ 09 марта 2019

Ответ @ Dimitre Novatchev , безусловно, правильный и элегантный, но есть обобщение (о котором ОП не спрашивал): что, если элемент, который вы хотите отфильтровать, также имеет дочерние элементы или текст, который вы хотите сохранить ?

Я полагаю, что этот незначительный вариант охватывает этот случай:

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

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <!-- drop DropMe elements, keeping child text and elements -->
    <xsl:template match="DropMe">
        <xsl:apply-templates/>
    </xsl:template>

</xsl:stylesheet>

Условие соответствия может быть сложным для указания других атрибутов и т. Д., И вы можете использовать несколько таких шаблонов, если отбрасываете другие вещи.

Итак, этот вход:

<?xml version="1.0" encoding="UTF-8"?>
<mydocument>
    <p>Here's text to keep</p>
    <p><DropMe>Keep this text but not the element</DropMe>; and keep what follows.</p>
    <p><DropMe>Also keep this text and <b>this child element</b> too</DropMe>, along with what follows.</p>
</mydocument>

производит этот вывод:

<?xml version="1.0" encoding="UTF-8"?><mydocument>
    <p>Here's text to keep</p>
    <p>Keep this text but not the element; and keep what follows.</p>
    <p>Also keep this text and <b>this child element</b> too, along with what follows.</p>
</mydocument>

Кредит XSLT Cookbook .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...