XSLT: Как выбрать братьев и сестер с условием - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть следующий 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>&#10;</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>&#10;</xsl:text>

</xsl:template>

</xsl:stylesheet>

Надеюсь, это понятно.

1 Ответ

0 голосов
/ 15 ноября 2018

Вы можете попробовать выбрать термины, которые не содержат ничего, кроме Unknown

<xsl:apply-templates select="term[not(info/ref[@obj-type!='Unknown'])]"/>

или добавить оператор if в ваш term[info/ref] шаблон

<xsl:template match="term[info/ref]">
    <xsl:if test="not(info/ref[@obj-type!='Unknown'])">
       <xsl:value-of select="@id"/>
       <xsl:text>,</xsl:text>
       <xsl:value-of select="name"/>
       <xsl:text>,</xsl:text>
       <xsl:text>&#10;</xsl:text>
    </xsl:if>

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