XPATH: несколько отрицаний для каждого - PullRequest
1 голос
/ 21 марта 2012

У меня есть следующий упрощенный XML:

<?xml version="1.0" encoding="UTF-8" ?>
<MATMAS05>
<IDOC BEGIN="1">
    <E1MARAM SEGMENT="1">
        <MSGFN>005</MSGFN>
        <MATNR>000000000000401436</MATNR>
        <E1MARCM SEGMENT="1">
            <MSGFN>005</MSGFN>
            <WERKS>A120</WERKS>
            <MMSTA>01</MMSTA>
        </E1MARCM>
        <E1MVKEM SEGMENT="1">
            <VKORG>0120</VKORG>
            <VMSTA>04</VMSTA>
        </E1MVKEM>
    </E1MARAM>
</IDOC>
</MATMAS05>

Если <WERKS>=A120 и <MMSTA> is NOT '01' or '02' or '03' ИЛИ, если <VKORG>=0120 и <VMSTA> is NOT '01' or '02' or '03', то <MATNR> должно быть сопоставлено с целевым XML.

Я придумал следующий XSLT:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output encoding="UTF-8" method="xml" indent="yes"/>

<xsl:template match="/*">
    <xsl:for-each
        select="IDOC[(E1MARAM/E1MVKEM[VKORG='0120'][not(VMSTA='01' or VMSTA='02' or VMSTA='03')])
            or (E1MARAM/E1MARCM[WERKS = 'A120'][not(MMSTA='01' or MMSTA='02' or MMSTA='03')])]">
        <Item>
            <ITEM_CODE>
                <xsl:value-of select="E1MARAM/MATNR"/>
            </ITEM_CODE>
        </Item>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Но если применить этот XSLT, я получу следующий нежелательный вывод (потому что <MMSTA>='01'):

<?xml version="1.0" encoding="UTF-8"?>
<Item>
<ITEM_CODE>000000000000401436</ITEM_CODE>
</Item>

Как я могу решить это?Я пробовал с этим выражением XPATH, но я не могу получить желаемый результат.Что я делаю не так в моем XPATH?

Спасибо за любые идеи с этим.С уважением, Питер

Ответы [ 3 ]

1 голос
/ 21 марта 2012

Я придумал это:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output  method="xml" indent="yes"/>

<xsl:template match="/*">
    <xsl:for-each
        select="IDOC[(E1MARAM/E1MARCM/WERKS/text() = 'A120' 
and descendant::MMSTA/text() != '01' 
and descendant::MMSTA/text() != '02' 
and descendant::MMSTA/text() != '03')
or (E1MARAM/E1MVKEM/VKORG/text() = '120' 
and descendant::VMSTA/text() != '01'
and descendant::VMSTA/text() != '02'
and descendant::VMSTA/text() != '03')]">
        <Item>
            <ITEM_CODE>
                <xsl:value-of select="E1MARAM/MATNR"/>
            </ITEM_CODE>
        </Item>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
1 голос
/ 21 марта 2012

Вот что я сделал:

//IDOC[(E1MARAM/E1MVKEM[VKORG='0120' and not(VMSTA='01' or VMSTA='02' or VMSTA='03')]) or (E1MARAM/E1MARCM[WERKS='A120' and not(MMSTA='01' or MMSTA='02' or MMSTA='03')])]

Я тоже попробовал ваш, и он работает, если вы добавляете корень в IDOC, так как MATMAS05 является фактическим корнем:

//IDOC[(E1MARAM/E1MVKEM[VKORG='0120'][not(VMSTA='01' or VMSTA='02' or VMSTA='03')])             or (E1MARAM/E1MARCM[WERKS = 'A120'][not(MMSTA='01' or MMSTA='02' or MMSTA='03')])]
1 голос
/ 21 марта 2012

not(MMSTA='01' or MMSTA='02' or MMSTA='03') всегда возвращает true, потому что .. MMSTA не является потомком IDOC, поэтому вы должны использовать //MMSTA

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