Не удается получить XSLT, ЕСЛИ вернуть XML - PullRequest
1 голос
/ 21 января 2011

Я хочу скопировать элементы, которые совпадают, когда

SECURITY_TYPE = 1 and SECURITY_SUB_TYPE = 99

OR

SECURITY_TYPE = 1 and SECURITY_SUB_TYPE = 12

Вот фрагмент `XML

<trade>
<PORTFOLIO_NUMBER>123</PORTFOLIO_NUMBER>
<TICKER>F</TICKER>
<SECURITY_TYPE>1</SECURITY_TYPE>
<SECURITY_SUB_TYPE>99</SECURITY_SUB_TYPE>
<PRICE>17.98</PRICE>
<QUANTITY>1</QUANTITY>
</trade>
<trade>
<PORTFOLIO_NUMBER>123</PORTFOLIO_NUMBER>
<TICKER>C</TICKER>
<SECURITY_TYPE>1</SECURITY_TYPE>
<SECURITY_SUB_TYPE>12</SECURITY_SUB_TYPE>
<PRICE>3.42</PRICE>
<QUANTITY>1</QUANTITY>
</trade>
<trade>
<PORTFOLIO_NUMBER>123</PORTFOLIO_NUMBER>
<TICKER>AAPL</TICKER>
<SECURITY_TYPE>2</SECURITY_TYPE>
<SECURITY_SUB_TYPE>4</SECURITY_SUB_TYPE>
<PRICE>300.34</PRICE>
<QUANTITY>1</QUANTITY>
</trade>

Вот мой неудачный XSLT. Что может быть не так?

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>

<xsl:template match="@* | node()">
<xsl:copy>
<xsl:if test="(SECURITY_TYPE = 1 and SECURITY_SUB_TYPE = 99) or
(SECURITY_TYPE = 1 and SECURITY_SUB_TYPE = 12)">

<xsl:value-of select="."/>

</xsl:if>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

Ответы [ 4 ]

2 голосов
/ 21 января 2011

Кажется, что вы пытаетесь создать что-то вроде правила идентификации, но вы пропускаете часть <xsl:apply-templates>, и ваше преобразование не идет глубже.

Вот краткий ипростое решение :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match=
  "trade[not(SECURITY_TYPE = 1)
       or
         (not(SECURITY_SUB_TYPE = 99)
       and
          not(SECURITY_SUB_TYPE = 12)
          )
         ]"/>

</xsl:stylesheet>

, когда это преобразование применяется к предоставленному документу XML (обернутым одним верхним элементом, чтобы сделать его правильно сформированным):

<t>
    <trade>
        <PORTFOLIO_NUMBER>123</PORTFOLIO_NUMBER>
        <TICKER>F</TICKER>
        <SECURITY_TYPE>1</SECURITY_TYPE>
        <SECURITY_SUB_TYPE>99</SECURITY_SUB_TYPE>
        <PRICE>17.98</PRICE>
        <QUANTITY>1</QUANTITY>
    </trade>
    <trade>
        <PORTFOLIO_NUMBER>123</PORTFOLIO_NUMBER>
        <TICKER>C</TICKER>
        <SECURITY_TYPE>1</SECURITY_TYPE>
        <SECURITY_SUB_TYPE>12</SECURITY_SUB_TYPE>
        <PRICE>3.42</PRICE>
        <QUANTITY>1</QUANTITY>
    </trade>
    <trade>
        <PORTFOLIO_NUMBER>123</PORTFOLIO_NUMBER>
        <TICKER>AAPL</TICKER>
        <SECURITY_TYPE>2</SECURITY_TYPE>
        <SECURITY_SUB_TYPE>4</SECURITY_SUB_TYPE>
        <PRICE>300.34</PRICE>
        <QUANTITY>1</QUANTITY>
    </trade>
</t>

желаемый, правильный результат получается :

<t>
   <trade>
      <PORTFOLIO_NUMBER>123</PORTFOLIO_NUMBER>
      <TICKER>F</TICKER>
      <SECURITY_TYPE>1</SECURITY_TYPE>
      <SECURITY_SUB_TYPE>99</SECURITY_SUB_TYPE>
      <PRICE>17.98</PRICE>
      <QUANTITY>1</QUANTITY>
   </trade>
   <trade>
      <PORTFOLIO_NUMBER>123</PORTFOLIO_NUMBER>
      <TICKER>C</TICKER>
      <SECURITY_TYPE>1</SECURITY_TYPE>
      <SECURITY_SUB_TYPE>12</SECURITY_SUB_TYPE>
      <PRICE>3.42</PRICE>
      <QUANTITY>1</QUANTITY>
   </trade>
</t>

Пояснение :

  1. правило идентификации (шаблон) копирует все узлы "как есть". Использование и переопределение правила идентификации является наиболее фундаментальным шаблоном проектирования XSLT.

  2. Существует один дополнительный шаблон, который переопределяет правило идентификации для любого элемента trade, который не удовлетворяет требуемым свойствам выбора .Этот шаблон не имеет тела и, следовательно, приводит к тому, что преобразование вообще не обрабатывается (удаляется) любой элемент trade, который не удовлетворяет требуемым условиям.

  3. В результатеиз 1. и 2. выше, только trade элементы (и их полные поддеревья), которые удовлетворяют требуемым условиям, копируются в выходные данные .

1 голос
/ 21 января 2011

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="trade[SECURITY_TYPE != 1
                               or SECURITY_SUB_TYPE != 99
                                  and SECURITY_SUB_TYPE != 12]"/>
</xsl:stylesheet>

Вывод: (с хорошо сформированным вводом, конечно):

<root>
    <trade>
        <PORTFOLIO_NUMBER>123</PORTFOLIO_NUMBER>
        <TICKER>F</TICKER>
        <SECURITY_TYPE>1</SECURITY_TYPE>
        <SECURITY_SUB_TYPE>99</SECURITY_SUB_TYPE>
        <PRICE>17.98</PRICE>
        <QUANTITY>1</QUANTITY>
    </trade>
    <trade>
        <PORTFOLIO_NUMBER>123</PORTFOLIO_NUMBER>
        <TICKER>C</TICKER>
        <SECURITY_TYPE>1</SECURITY_TYPE>
        <SECURITY_SUB_TYPE>12</SECURITY_SUB_TYPE>
        <PRICE>3.42</PRICE>
        <QUANTITY>1</QUANTITY>
    </trade>
</root>
1 голос
/ 21 января 2011

Используйте шаблон преобразования идентификаторов плюс один шаблон, подавляющий копирование элементов, не соответствующих условию:

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="trade[not((SECURITY_TYPE = 1 and SECURITY_SUB_TYPE = 99) or (SECURITY_TYPE = 1 and SECURITY_SUB_TYPE = 12))]"/>

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

0 голосов
/ 21 января 2011

Я добавил корневой элемент . Решение ниже работает. Вы должны применять условную логику только к элементу , а не ко всем элементам.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
  <xsl:output method="xml" indent="yes"/>


  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates />
    </xsl:copy>
  </xsl:template>

  <!-- parse the <trade> element -->
  <xsl:template match="trade">
    <xsl:copy>
      <xsl:if test="(SECURITY_TYPE = 1 and SECURITY_SUB_TYPE = 99) or
        (SECURITY_TYPE = 1 and SECURITY_SUB_TYPE = 12)">

        <xsl:value-of select="."/>

      </xsl:if>
    </xsl:copy>
  </xsl:template>

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