2015-06-29 8 views
1

У меня есть некоторые XML-файлы, как показано ниже. Они содержат все разные древовидные структуры, а некоторые элементы имеют атрибуты.Запустите два шаблона для одного и того же узла (XSLT)

<root> 
    <element n="A"> 
    <element n="B"> 
     <attribute a="1"/> 
     <attribute a="2"/> 
    </element> 
    <element n="C"> 
     <element n="D"> 
     <attribute a="3"/> 
     </element> 
    </element> 
    </element> 
</root> 

Я хочу преобразовать эти файлы с помощью XSLT, чтобы получить следующий результат. Я должен сохранить структуру дерева, а также создать список всех элементов с их атрибутами:

<root> 
    <structure> 
    <newElement n="A"> 
     <newElement n="B"> 
     <newAttribute a="1"/> 
     <newAttribute a="2"/> 
     </newElement> 
     <newElement n="C"> 
     <newElement n="D"> 
      <newAttribute a="3"/> 
     </newElement> 
     </newElement> 
    </newElement> 
    </structure> 
    <list> 
    <listElement n="A"/> 
    <listElement n="B"> 
     <listAttribute a="1"/> 
     <listAttribute a="2"/> 
    </listElement> 
    <listElement n="C"/> 
    <listElement n="D"> 
     <listAttribute a="3"/> 
    </listElement> 
    </list> 
</root> 

Я пытаюсь запустить два различных шаблонов «e1» и «e2» для одного узла «элемент», но это Безразлично» т работы. Кажется, что первый шаблон игнорируется. Так что я должен изменить?

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

<xsl:template match="/"> 
    <root> 
    <structure> 
     <xsl:apply-templates name="e1"/> 
    </structure> 
    <list> 
     <xsl:apply-templates name="e2"/> 
    </list> 
    </root> 
</xsl:template> 

<xsl:template match="element" name="e1"> 
    <newElement> 
    <xsl:attribute name="n"> 
     <xsl:value-of select="@n"/> 
    </xsl:attribute> 
    <xsl:apply-templates name="a1"/> 
    <xsl:apply-templates name="e1"/> 
    </newElement> 
</xsl:template> 

<xsl:template match="attribute" name="a1"> 
    <newAttribute> 
    <xsl:attribute name="a"> 
     <xsl:value-of select="@a"/> 
    </xsl:attribute> 
    </newAttribute> 
</xsl:template> 

<xsl:template match="element" name="e2"> 
    <listElement> 
    <xsl:attribute name="n"> 
     <xsl:value-of select="@n"/> 
    </xsl:attribute> 
    <xsl:apply-templates name="a2"/> 
    </listElement> 
    <xsl:apply-templates select="element"/> 
</xsl:template> 

<xsl:template match="attribute" name="a2"> 
    <listAttribute> 
    <xsl:attribute name="a"> 
     <xsl:value-of select="@a"/> 
    </xsl:attribute> 
    </listAttribute> 
</xsl:template> 

</xsl:stylesheet> 

ответ

5

Это не является допустимым использовать атрибут name на xsl:apply-templates. Я предполагаю, что ваша обработка XSLT просто игнорирует имя в этом случае и просто дон простая <xsl:apply-templates />.

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

Попробуйте этот XSLT

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

<xsl:template match="/"> 
    <root> 
    <structure> 
     <xsl:apply-templates mode="e1"/> 
    </structure> 
    <list> 
     <xsl:apply-templates mode="e2"/> 
    </list> 
    </root> 
</xsl:template> 

<xsl:template match="element" mode="e1"> 
    <newElement n="{@n}"> 
    <xsl:apply-templates mode="e1"/> 
    </newElement> 
</xsl:template> 

<xsl:template match="attribute" mode="e1"> 
    <newAttribute a="{@a}"/> 
</xsl:template> 

<xsl:template match="element" mode="e2"> 
    <listElement n="{@n}"> 
    <xsl:apply-templates select="attribute" mode="e2"/> 
    </listElement> 
    <xsl:apply-templates select="element" mode="e2"/> 
</xsl:template> 

<xsl:template match="attribute" mode="e2"> 
    <listAttribute a="{@a}"/> 
</xsl:template> 
</xsl:stylesheet> 

Обратите внимание на использование "Attribute Value Templates" здесь, чтобы упростить XSLT.

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