2017-02-20 6 views
1

Я пытаюсь преобразовать Doxygen XML в текстовый вывод с XSLT. Doxygen возвращает эту XML структуру:XSLT: выберите все элементы без поддерева

<detaileddescription> 
    <para>a long text with <formula id="6">$ \LaTeX $</formula> code</para> 
    <para> 
     <simplesect kind="see"> 
      <para> 
       <ulink url="url">url description</ulink> 
      </para> 
     </simplesect> 
    </para>  
</detaileddescription> 

Я пытаюсь выбрать только тот para узел, который не содержит simplesect узла или какую-либо другую «сложную структуру дерева».
Я стараюсь это XPath:

detaileddescription/para/node() 

, но это также будет возвращать simplesect/para узел.
Итак, как я могу выбрать только узел para, который не содержит узла text() или узла formula в качестве родного брата?

+1

Чтобы выбрать 'para', который не содержит' simplesect', вы можете использовать '/ detaildescription/para [not (simplesect)]'.Я не уверен, что вы подразумеваете под «* любой другой» сложной древовидной структурой ». *« –

+0

Какой элемент или элемент 'para' вы хотите выбрать? – zx485

ответ

0

XPath, чтобы получить только ulink узел будет

//para[count(descendant::*) &lt; 2 and count(text()) = 0] 

Полный XSLT-1.0 для достижения этой цели является

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

    <xsl:template match="text()" /> 

    <xsl:template match="//para[count(descendant::*) &lt; 2 and count(text()) = 0]"> 
    <xsl:copy-of select="." /> 
    </xsl:template> 

</xsl:stylesheet> 

выход которого

<?xml version="1.0"?> 
<para> 
    <ulink url="url">url description</ulink> 
</para> 
+0

Спасибо, что помогает много, я использую для выражения соответствия: 'пункта [Count (нижестоящего :: *) > 0 и количество (текст()) > 0]' , потому что я хотел бы получить узел ' длинный текст с формулой id =" 6 "> $ \ LaTeX $ код' Так что мне нужен текстовый узел всегда и если существует узел-формула. – Phil

+1

@Phil Пожалуйста, покажите полную таблицу стилей XSLT в вопросе, а также ожидаемый текст. Благодарю. –

1

Выражение detaileddescription/para/node() не выбирает узел simplesect/para. Он выбирает элемент simplesect, но не выбирает его дочерние элементы. Я думаю, что ваше замешательство в том, что происходит после, вы выбираете узел. Вы не показали нам, что вы делаете с выбранными узлами, но если, например, вы применяете инструкцию xsl:copy-of к выбранным узлам, которая будет копировать не только выбранные узлы, но и все их дочерние и потомки.

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

0

Вы написали узел узла, который не содержит ... любую ... сложную древовидную структуру.

Тогда сделайте, как Вы писали:

  • Написать шаблон, соответствующий para.
  • Чтение (прямое) дочерних текстовых узлов, но содержащих только «настоящий» текст (не пустые).
  • Затем проверьте, действительно ли у вас что-то есть.
  • Если да (ваш para содержит некий пустой текст (забыли о «более глубокие» расположенные текстовые узлы)), выполните преобразование идентичности.
  • В противном случае ваш para не будет отображаться.

У вас есть полное решение. Я добавил strip-space, чтобы избежать пустых строк вывода.

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="para"> 
    <xsl:variable name="txt" select="text()[normalize-space()]"/> 
    <xsl:if test="$txt"> 
     <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
    <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy> 
    </xsl:template> 
</xsl:transform> 
Смежные вопросы