Мне нужно удалить некоторые узлы в моем файле XML, в котором он содержит определенный метод и в каком порядке он появляется, например, здесь вход:Как удалить определенный узел на основе атрибута в XML с помощью XSLT или Xquery?
<root>
<node id="a">
<section id="a_1">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1">
<user id="b_1b" method="pause">
<attribute>a</attribute>
</user>
<user id="b_1b" method="run">
<attribute>a</attribute>
</user>
<user id="b_1a" method="run">
<attribute>
<name>John</name>
</attribute>
</user>
<user id="b_1a" method="pause">
<attribute>a</attribute>
</user>
</section>
<section id="b_1" method="create">
<user id="b_1b" method="stop">
<attribute>a</attribute>
</user>
<user id="b_1a" method="stop">
<attribute>a</attribute>
</user>
<user id="b_1b" method="run">
<attribute>a</attribute>
</user>
<user id="b_1b" method="pause">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a" method="run">
<attribute>
<name>John</name>
</attribute>
</user>
</section>
</node>
Если я использую этот метод:
<xsl:transform version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://localhost"
exclude-result-prefixes="my">
<!-- Copy everything by default -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match=" user[not(@method eq 'stop')][not(. is my:last(.))]
| user[ @method eq 'stop' ][not(. is my:last(.))]
| user[not(@method eq 'stop')][my:last(.)/@method eq 'stop']"/>
<!-- Get the last user for this section & user id -->
<xsl:function name="my:last">
<xsl:param name="user"/>
<xsl:sequence select="($user/../../section[@id eq $user/../@id]
/user [@id eq $user/@id]
)
[last()]"/>
</xsl:function>
</xsl:transform>
результат будет:
<root>
<node id="a">
<section id="a_1">
<item id="0">
<attribute>
<color>
Red
</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>
Red
</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1">
</section>
<section id="b_1" method="create">
<user id="b_1a" method="stop">
<attribute>
a
</attribute>
</user>
<user id="b_1b" method="pause">
<attribute>
a
</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a" method="run">
<attribute>
<name>
John
</name>
</attribute>
</user>
</section>
</node>
</root>
, в то время как ожидаемый выход:
<root>
<node id="a">
<section id="a_1">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1">
</section>
<section id="b_1" method="create">
<user id="b_1a" method="stop">
<attribute>a</attribute>
</user>
**<user id="b_1b" method="run">
<attribute>a</attribute>
</user>**
<user id="b_1b" method="pause">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a" method="run">
<attribute>
<name>John</name>
</attribute>
</user>
</section>
</node>
</root>
так вот как работает заказ. Если происходит «остановка», тогда любой другой узел с другими методами с одним и тем же идентификатором пользователя (например, пауза и запуск) будет удален. Но если это не тот узел с самой «остановкой» и всем узлом до этого «stop» будет удален.
Это должно быть указано в том же идентификаторе раздела, и он удалит только пользовательский узел (оставьте идентификатор раздела, даже если он пуст после удаления пользовательского узла). Надеюсь, что это не смущает.
Можно ли это сделать только с помощью XSLT? или мне нужно использовать xQuery для перемещения по каждому узлу? Может кто-нибудь просветить меня? спасибо.
John
Я думаю, что ваше повторение является опечаткой, поскольку идентификаторы XML должны быть уникальными (если это действительно атрибут id). –
Вы можете сделать это с помощью XSLT (или XQuery, я думаю), не нужно использовать оба. – LarsH
Просьба пояснить, что вы подразумеваете под «если« остановка »происходит последним». Сначала я думал, что вы имели в виду, когда с методом = "stop" происходит как последний ребенок. Но поскольку это не совпадает с примером, который вы дали, я предполагаю, что нет. –