как использовать xsl для различения двух похожих тегов (переменных)

#xml #xslt

#xml #xslt

Вопрос:

Мне нужно создать xsl, способный читать два XML-файла, которые имеют одинаковую структуру, за исключением первого тега:

входящий xml:

 <beans:beans> <fix-inbound> <message></message> </fix-inbound> </beans:beans>
  

исходящий xml:

 <beans:beans> <fix-outbound> <message></message> </fix-outbound> </beans:beans>
  

решения, которые я смог найти, были:

  • создание двух файлов для чтения входящих и исходящих
  • ужасно, если нравится :

     <xsl:if test="fix-inbound">
        code to read the content
    </xsl:if>
    <xsl:if test="fix-outbound"> 
        same piece of code to read the content 
    </xsl:if>
      
  • использование переменной в my, <xsl:for-each select="$valueOfMyFirstTag"> значением которой может быть входящее исправление или исходящее исправление

Однако я понятия не имею, как получить значение первого тега. Возможно ли это с помощью xsl?

Есть ли более элегантный способ решить эту проблему?

Комментарии:

1. Какое значение вы пытаетесь получить? Вы пытаетесь напечатать значение message , используя шаблон, который обрабатывает оба возможных родительских элемента?

2. Непонятно, почему вас это беспокоит? Вам нужно выражение XPath для выбора внутренних элементов? Похоже, вы страдаете от последствий обработки в стиле push. Предоставьте желаемый результат для обоих ваших входных образцов.

3. Хороший вопрос, 1. Смотрите мой ответ о простом и коротком способе выполнения желаемой обработки без каких-либо условных инструкций XSLT. Добро пожаловать в мощь и элегантность XSLT.

4. @lwburk : Я использовал for-each для навигации в моей структуре xml следующим образом: <xsl:for-each select=»beans: beans/ fix-inbound / message»>, но теперь мой xml может содержать: beans: beans/ fix-inbound или fix-outbound / message . Я не знаю, как заставить, используя переменную или выражение, для каждого принять этот новый параметр на этом уровне xml

Ответ №1:

Вы могли бы использовать

 <xsl:for-each select="/*/fix-inbound | /*/fix-outbound">
  

(или, в зависимости от вашего варианта использования, используйте apply-templates вместо for-each ).

Ответ №2:

Совсем не ясно, что вы пытаетесь сделать или где у вас не получается, но из вашего поста видно, что вы еще не открыли для себя прелесть правил шаблонов, которые формируют сердце настоящей обработки XSLT. Возможно, вы также еще не открыли для себя силу подстановочных знаков (*) в путях или псевдооператора «//».

Ответ №3:

Использовать:

 <xsl:template match="/">
 <xsl:apply-templates select="/*/*[1]"/>
</xsl:template>

<xsl:template match="fix-inbound">
 <!-- Perform whatever processing is necessary  -->
</xsl:template>

<xsl:template match="fix-outbound">
 <!-- Perform whatever processing is necessary  -->
</xsl:template>
  

Объяснение:

<xsl:apply-templates select="/*/*[1]"/> Инструкция заставляет выбирать для выполнения и применять любой шаблон, который наилучшим образом соответствует первому дочернему элементу верхнего элемента.

Если документ относится к первому типу, применяется соответствие шаблону fix-inbound .

Если документ второго типа, применяется соответствие шаблону fix-outbound .

Обратите внимание: В этом решении вообще не используются условные инструкции — в XSLT они редко необходимы, и если условные инструкции присутствуют, это сигнал о том, что может потребоваться некоторый рефакторинг.