2012-06-07 6 views
1

Я только начал изучать XML & XSLT и задать короткий вопрос относительно Xpath.XSLT Xpath wildcard

Вот код XML:

<root> 

<shop> 
    <person> 
     <employee> 
      <name> Alexis </name> 
      <role> Manager </role> 
      <task> Sales </task> 
     </employee> 
    </person> 
</shop> 

<person> 
    <employee> 
     <role> Supervisor </role> 
     <name> Blake </name> 
     <task> Control </task> 
    </employee> 
</person> 


</root> 

и вот код XSLT:

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

<xsl:template match="root"> 
<html><head></head> 
<body><xsl:apply-templates/> 
</body> 
</html> 
</xsl:template> 


<xsl:template match="shop"> 
<xsl:apply-templates select="/root/*/*"/> 
</xsl:template> 

<xsl:template match="employee"> 
<u> <xsl:apply-templates select="name"/> </u> 
(Task: <xsl:apply-templates select="task"/>) 
<br></br> 
</xsl:template> 

<xsl:template match="person2"> 
<xsl:apply-templates /> 
</xsl:template> 

</xsl:stylesheet> 

Выход:

Alexis (Task: Sales) 
Blake (Task: Control) 
Blake (Task: Control) 

Я не понимаю, почему последняя часть дублируется? Я знаю, что это из-за этой части кода XSLT:

<xsl:apply-templates select="/root/*/*"/> 

, но это только потому, что я был возиться с кодом и отображением его в Firefox. Однако я не понимаю, почему.

Из того, что я понимаю, это выбрать все элементы внукам «корень», например, так:

корень/магазин/чел

но почему не повторяется Алексис, а? Только Blake повторяется ...

ответ

1

В шаблоне соответствия корня, вы <xsl:apply-templates/>, который подберет первый магазина и человека элементов. Что касается элемента людей, не существует определенный шаблон для этого, и поэтому XSLT будет продолжать соответствовать его дочерним элементам и подобрать сотрудника для "Блейка

Однако, есть согласование шаблон для магазин, и проблема действительно в том, что вы делаете в шаблоне, который соответствует ему.

<xsl:apply-templates select="/root/*/*"/> 

Поскольку вы начали выражение XPath с /root это начнет mathing относительно корневого элемента документа, а не магазина элемента вы в настоящее время расположены на. Это означает, что он выберет элементы /root/shop/person и /root/person/employee, который приведет к дублированию «Блейк». Однако, поскольку вы не сопоставляете элемент employee для «Alexis» в другом месте, это выводится только один раз.

Вы, вероятно, нужно сделать именно это вместо того, чтобы совпадать с Сотрудника элемент

<xsl:apply-templates select="*/*"/> 

Это будет соответствовать всем гранд-потомков текущего элемента. * будет соответствовать дочернему элементу, и поэтому */* будет соответствовать дочерним элементам дочерних элементов.

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" indent="yes" /> 

    <xsl:template match="root"> 
     <html> 
     <head/> 
     <body> 
      <xsl:apply-templates/> 
     </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="employee"> 
     <u> 
     <xsl:value-of select="name"/> 
     </u> 
     <xsl:value-of select="concat(' (Task:', task, ')')"/> 
     <br/> 
    </xsl:template> 
</xsl:stylesheet> 

Применительно к вашему XML, следующий выход

<html> 
    <head> 
    </head> 
    <body> 
     <u> Alexis </u> (Task: Sales)<br> 
     <u> Blake </u> (Task: Control)<br> 
    </body> 
</html> 
+0

+1 Nice объяснение и альтернативные таблицы стилей. –

+0

Большое спасибо за ваш ответ! Я не пытаюсь показать, что это только сотрудники или что-то еще, это просто вопрос экзамена, который я хочу понять. Я понимаю, как вы получите: /корень/магазин/человек и/корень/лицо/работник но поскольку работник является потомком человека для этой части: /корень/магазин/человек/работник то почему не является ли Алексис частью дублированного выхода? Кроме того, что именно это делает */* ?? – shadowz1337

+0

Я расширил свой ответ, надеюсь, попробуем и объясню немного больше, и что означает '*/*'. –

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