2016-08-30 2 views
0

Возможно ли, чтобы xsl: apply-templates были ограничены только для соответствия узлу, не пытаясь сопоставить вложенные элементы?Ограничить использование XSLT-шаблона только текущим узлом?

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

У меня есть документ, состоящий из элементов раздела и поля.

Раздел может содержать вложенные элементы Раздела или Элементы поля. Элементы поля не имеют гнездования.

В качестве примера, для поля, фрагмент кода шаблона является:

<xsl:template match="Field" mode="Field"> 

    <xsl:apply-templates select="." mode="FieldHeight" /> 

    ..... 

</xsl:template> 

<xsl:template match="Field[LayoutTitlePosition = 'top']" mode="FieldHeight"> 
    <xsl:attribute name="h" select="$glTopFieldHeight" /> 
</xsl:template> 

<xsl:template match="Field[LayoutTitlePosition = ('left', 'right', 'none')]" mode="FieldHeight"> 
    <xsl:attribute name="h" select="$glHorzFieldHeight" /> 
</xsl:template> 

То же самое может быть достигнуто с помощью XSL: выбрать/XSL: когда заявления, но я нахожу параметры поиска соответствия симпатичнее синтаксис и проще в обслуживании. Я могу поддерживать общий шаблон поля и переопределять определенные части на основе ввода. Поскольку поля не являются вложенными, мне не нужно беспокоиться о том, что «субфиты» совпадают.

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

EDIT Пример выпуска.

Я попытался создать минимальный пример для воспроизведения проблемы. Входной документ:

<?xml version="1.0" encoding="UTF-8"?> 
<Root> 
    <Section> 
     <!-- no title --> 
     <Section> 
      <Title>Sub section title</Title> 
      <Field> 
       <Type>Text</Type> 
      </Field> 
     </Section> 
    </Section> 
</Root> 

XSL-преобразование документа:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:output indent="yes" /> 

<xsl:template match="*" > 
    <subform layout="tb"> 
     <xsl:apply-templates select=".[name() = 'Section']" mode="Heading" /> 
     <xsl:apply-templates select=".[name() = 'Field']" mode="Field" /> 
     <xsl:apply-templates select="*[name() = ('Section', 'Field')]" /> 
    </subform> 
</xsl:template> 

<xsl:template match="Section[Title]" mode="Heading"> 
    <subform layout="tb"> 
     <xsl:call-template name="drawHeading" /> 
    </subform> 
</xsl:template> 

<xsl:template name="drawHeading"> 
    <Heading><xsl:value-of select="Title" /></Heading> 
</xsl:template> 

<xsl:template match="Field" mode="Field"> 
    <field name="{@Name}"> 
    </field> 
</xsl:template> 

выход, от преобразования входного документа:

<?xml version="1.0" encoding="UTF-8"?> 
<subform layout="tb"> 
    <subform layout="tb"> 
     <subform layout="tb"> 
      <Heading>Sub section title</Heading> 
     </subform> 
     <subform layout="tb"> 
      <subform layout="tb"> 
       <Heading>Sub section title</Heading> 
      </subform> 
      <subform layout="tb"> 
       <field name=""/> 
      </subform> 
     </subform> 
    </subform> 
</subform> 

Казалось, указанный в заголовке подраздела при совпадении, когда родительский раздел без заголовка не совпал.

В результате чего я хотел достичь является:

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

     <subform layout="tb"> 
      <subform layout="tb"> 
       <Heading>Sub section title</Heading> 
      </subform> 
      <subform layout="tb"> 
       <field name=""/> 
      </subform> 
     </subform> 
    </subform> 
</subform> 

Если название присутствует в исходном документе, например:

<?xml version="1.0" encoding="UTF-8"?> 
<Root> 
    <Section> 
     <Title>Section title</Title> 
     <Section> 
      <Title>Sub section title</Title> 
      <Field> 
       <Type>Text</Type> 
      </Field> 
     </Section> 
    </Section> 
</Root> 

Затем он должен производить:

<?xml version="1.0" encoding="UTF-8"?> 
<subform layout="tb"> 
    <subform layout="tb"> 
     <subform layout="tb"> 
      <Heading>Section title</Heading> 
     </subform> 
     <subform layout="tb"> 
      <subform layout="tb"> 
       <Heading>Sub section title</Heading> 
      </subform> 
      <subform layout="tb"> 
       <field name=""/> 
      </subform> 
     </subform> 
    </subform> 
</subform> 
+0

Рассмотрите, пожалуйста, образец ввода, результат, который вы хотите, код, который у вас есть, и полученный результат. Боюсь, я не понимаю, зачем это делать. '

+0

Спасибо. Я добавил пример. – dave

+0

Пожалуйста, также опубликуйте результат, который вы хотите достичь. –

ответ

1

Кажется, что просто используя два специализированных шаблона для Field и Title следует:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:output indent="yes" /> 

<xsl:template match="*" > 
    <subform layout="tb"> 
     <xsl:apply-templates/> 
    </subform> 
</xsl:template> 


<xsl:template match="Title"> 
    <subform layout="tb"> 
     <Heading><xsl:value-of select="." /></Heading> 
    </subform> 
</xsl:template> 

<xsl:template match="Field"> 
    <subform layout="tb"> 
     <field name="{@Name}"></field> 
    </subform> 
</xsl:template> 

</xsl:stylesheet> 

В сети по адресу http://xsltransform.net/pPJ8LUX.

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