2012-03-21 2 views
1

У меня есть следующий упрощенный XML:XPATH: множественные отрицания в наличии для каждого

<?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?

Благодарим вас за любые идеи. С наилучшими пожеланиями, Питер

ответ

1

Это то, что я сделал :

//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')])] 

Я пробовал и ваш, и он работает, если лет u добавьте корень в 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')])] 
+0

спасибо jdwilemo, это похоже на решение Аравина, и я предпочитаю ваш, потому что я добавляю корень только один раз +1 – Peter

1

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

+0

Спасибо, Аравин, хорошо работает; он аналогичен решению jdwilemo с корневым узлом; извлеченный урок ;-) +1 – Peter

+0

Добро пожаловать :) –

1

Я пришел с этим:

<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> 
+0

Спасибо, Баран, вы также подразумеваете отношение к корневому узлу. Это была моя большая ошибка в начале. Я пошел с другим решением, потому что выражение короче; еще +1 – Peter

Смежные вопросы