Как мне написать предикат для этого в одном xpath? - PullRequest
0 голосов
/ 23 апреля 2019

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

if <Position isAdded="1"> exists then this is what I need.

if <Position isAdded="1"> doesn't exist, and <Position isUpdated=1> exists, that I need this element.

I never should pull <Position isDeleted=1>

If isAdded and isUpdated don't exist, then I need to get the value from 
<Position> without any attributes.

Это то, что я пробовал до сих пор / Root / Effective_Change / Position [не (существует (@isDeleted))]] [существует (@isAdded)] * ​​

получить мне элемент isAdded.Я могу добавить множественный выбор, когда и проверить для каждого атрибута.Я просто пытаюсь понять, можно ли это сделать в одном xpath.Поскольку в моем xml много элементов, я не хочу делать это для каждого элемента.Следовательно, пытаясь построить функцию.Например,

/Root/Effective_Change/Position[if (exists(@isAdded then
     .[@isAdded]
else if exists(@isUpdated) then 
.[@isUpdated] else not(exists(@isDeleted))] 

Образец xml

<?xml version="1.0" encoding="UTF-8"?>
<Root>
    <Effective_Change Sequence="1">
        <Position isUpdated="1">
            <Business_Title>Updated Product Engineer</Business_Title>
            <Worker_Type>Regular</Worker_Type>
        </Position>
        <Position isAdded="1">
            <Business_Title>Product Engineer</Business_Title>
            <Worker_Type>Regular</Worker_Type>
        </Position>
        <Position isDeleted="1">
            <Business_Title>Deleted Product Engineer</Business_Title>
            <Worker_Type>Regular</Worker_Type>
        </Position>
        <Position>
            <Business_Title>Product Engineer</Business_Title>
            <Worker_Type>Regular</Worker_Type>
        </Position>
    </Effective_Change>
</Root>

Фактический файл может иметь эти атрибуты на нескольких уровнях.например:

<Position isUpdated="1">
    <Business_Title>Updated Product Engineer</Business_Title>
    <Worker_Type isDeleted="1">Temporary</Worker_Type>
    <Worker_Type isAdded="1">Regular</Worker_Type>
</Position>

Я использую эту функцию для получения не удаленных данных

<xsl:function name="this:getNonDeletedElement">
    <xsl:param name="element"/>
    <xsl:variable name="nodeName">
        <xsl:value-of select="$element[1]/name()"/>
    </xsl:variable>
    <xsl:choose>
        <xsl:when test="exists($element/ancestor::*[name() = 'Effective_Change']//*[not(exists(@isDeleted))]/*[name() = $nodeName][not(exists(@isDeleted))])">
            <xsl:value-of select="$element/ancestor::*[name() = 'Effective_Change']//*[not(exists(@isDeleted))]/*[name() = $nodeName][not(exists(@isDeleted))]"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="''"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:function>

Эта функция, тем не менее, будет по-прежнему возвращать строки isAdded, isUpdated и без атрибутов.В этом случае, если isAdded существует, мне нужно, чтобы, если isAdded не существует и isUpdated существует, тогда мне нужно это, в противном случае строка без атрибутов.

Я использую это для проверки isAdded

<xsl:function name="this:isElementAdded">
    <xsl:param name="element"/>
    <xsl:choose>
        <xsl:when test="$element/../@isAdded or $element/@isAdded or exists($element/ancestor::*[@isAdded and name(..)='Effective_Change'])">
            <xsl:value-of select="true()"/>                                                 
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="false()"/>                        
        </xsl:otherwise>
    </xsl:choose>
</xsl:function> 

Мне интересно, есть ли более простой способ сделать это.

...