У меня есть следующий XML:
<?xml version="1.0" encoding="UTF-8"?>
<thesaurus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<term id="01">
<name>
<value>green</value>
</name>
<info>
<ref rid="12" obj-type="Building" />
</info>
<info>
<ref rid="13" obj-type="House" />
</info>
<info>
<ref rid="14" obj-type="Apartment"/>
</info>
</term>
<term id="02">
<name>
<value>blue</value>
</name>
<info>
<ref rid="24" obj-type="Unknown"/>
</info>
<info>
<ref rid="26" obj-type="Unknown"/>
</info>
<info>
<ref rid="29" obj-type="Unknown"/>
</info>
</term>
<term id="03">
<name>
<value>yellow</value>
</name>
</term>
<term id="04">
<name>
<value>red</value>
</name>
<info>
<ref rid="40" obj-type="Hotel"/>
</info>
<info>
<ref rid="41" obj-type="Building"/>
</info>
<info>
<ref rid="43" obj-type="House"/>
</info>
</term>
<term id="05">
<name>
<value>purple</value>
</name>
</term>
<term id="06">
<name>
<value>magenta</value>
</name>
<info>
<ref rid="60" obj-type="Building"/>
</info>
<info>
<ref rid="62" obj-type="Unknown"/>
</info>
<info>
<ref rid="64" obj-type="House"/>
</info>
</term>
</thesaurus>
Я хочу вот что:
1) Выбрать все <term>
теги, которые не имеют тега <info>
.Это уже выполняется с помощью первых шаблонов применения: select = "term [not (info)]" * в XSLT ниже.
2) Выберите все теги <term>
, когда его *Тег 1014 * содержит obj-type="Unknown"
один или несколько раз, но не выбирайте его, если он окружен obj-types
со значениями, отличными от " Unknown " (например, «Здание» или «Дом»).
*** Внутри тега <info>
при наличии братьев или сестер obj-type
с другими значениями требуется по крайней мере одно значение «Неизвестно», чтобы тег <term>
не был выбран.
Если XSLT работает хорошо, будут выбраны следующие теги:
02, 03, 05
где:
01не будет выбран, потому что он содержит <info>
тегов, и ни один из этих тегов не имеет obj-type = 'Unknown'
02 будет выбран, потому что есть три множественных значения 'Unknown', и нетбудут выбраны другие значения, отличные от «Неизвестно»
03, поскольку он не содержит <info>
тегов
04 не будет выбран, поскольку он содержит <info>
тегов со значениями obj-type
отличается от «Неизвестно».
05 будет выбрано, потому что нет информационных тегов.
06 не будет выбрано, потому что, хотя есть одно значение «Неизвестно», все остальные братья и сестры <ref>
имеют значениеobj-type
отличается от «Неизвестно».
*** ПОМНИТЕ: Внутри тега <info>
, когда у obj-type
родственных элементов с другими значениями, требуется как минимум одно значение «Неизвестно» для *Тег 1055 * не будет выбран.
Я использую XSLT ниже.С помощью первого apply-templates я могу выбрать все теги без тега <info>
.
Со вторым apply-templates я могу выбрать все <term>
теги, которые содержат тег <ref>
с obj-type="Unknown"
, но я не знаю, как сообщить XSLT, что если существуют типы obj с другим значением, не выбирайте соответствующий тег <term>
.
Я пытался использовать for-each и условное, чтобы перебрать все дочерние элементы <ref>
и проверить, было ли у одного из братьев и сестер значение, отличное от 'Unknown', чтобы не выбрать его <term>
parent,но безрезультатно.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="text"/>
<xsl:template match="/thesaurus">
<xsl:apply-templates select="term[not(info)]"/>
<xsl:apply-templates select="term[info/ref[@obj-type='Unknown']]"/>
</xsl:template>
<xsl:template match="term">
<xsl:value-of select="@id"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="name"/>
<xsl:text>,</xsl:text>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="term[info/ref]">
<xsl:value-of select="@id"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="name"/>
<xsl:text>,</xsl:text>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
Надеюсь, это понятно.