2015-06-15 2 views
0

Я пытаюсь пересечь все узлы с текстом в моем документе из определенного места.XSLT получить все узлы с текстом

<xsl:template name="interpret_text"> 
    <xsl:param name="location"/> 
    <xsl:for-each select="$location//text()"> 
    <xsl:choose> 
     <xsl:when test="name(.) = tag_im_looking_for"> 
     <!-- various code stuff and closing tags --> 

Этот код является функциональным, за исключением случаев, когда вы можете заметить мою проблему. Когда я вхожу в цикл for-each, текст забыл свой тег. значение current() является сырым текстом и больше не запоминает его владельца. Я попытался настроить свой алгоритм на выбор узлов, а затем только разбор текста с текстом. Например:

<xsl:template name="interpret_text"> 
    <xsl:param name="location"/> 
    <xsl:for-each select="$location//node()"> 
    <xsl:if test="not(text() = '')"> 
     <xsl:choose> 
     <xsl:when test="name(.) = tag_im_looking_for"> 
      <!-- various code stuff and closing tags --> 

Однако каким-то образом этот алгоритм работает для меня. Предположим, что xml ниже не имеет лишних пробелов, которые необходимо нормализовать.

<a> 
    <b> 
    before 
    <c>inner text</c> 
    after 
    </b> 
</a> 

Вверх algorthim будет работать в этом порядке.

before 
inner text 
after 

Дно будет работать в таком порядке

b context 
c context 

Но есть текст до и после того, как контекст с, и мне нужно, чтобы разобрать «до», то «внутренний текст», то после". Примечание. Мне нужен этот алгоритм для работы на любой глубине и с текстом «до» или «после» или без него. Есть ли простой путь от решения узла или текстового решения, чтобы получить желаемый результат?

+0

Может быть, вы хотите 'тока()'? –

+0

Знаете ли вы о синтаксисе 'node [cond]' xpath? – o11c

+0

Также я не вижу смысла иметь «xsl: param» вместо того, чтобы просто использовать текущий узел во время вызова ... – o11c

ответ

0

Неясно мне, что место есть, но этот пример:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0"> 
<xsl:output indent="yes"/> 
<xsl:template match="/"> 
    <sample>  <xsl:call-template name="interpret_text"> 
     <xsl:with-param name="location" select="."/> 
    </xsl:call-template> 
    </sample> 

</xsl:template> 
<xsl:template name="interpret_text"> 
    <xsl:param name="location"/> 
    <xsl:for-each select="$location//text()"> 
     <xsl:if test="string-length(normalize-space(.))>0"> 
     <elem> 
      Parent: <xsl:value-of select="name(parent::*)"/>, Text: <xsl:value-of select="normalize-space(.)"/> 
     </elem> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

выход ли этот выход с входной выборки:

<sample> 
    <elem> 
      Parent: b, Text: before</elem> 
    <elem> 
      Parent: c, Text: inner text</elem> 
    <elem> 
      Parent: b, Text: after</elem> 
</sample 

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

+0

parent :: * был оператором, которого я искал! Благодаря! – Brolita

0

Мне нужно было угадать немного о ваших реальных потребностях, но это должно быть довольно близко.

стилевых:

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/root"> 
    <output> 
     <xsl:apply-templates match="foo"/> 
    </output> 
    </xsl:template> 
    <xsl:template name="interpret-text"> 
    <xsl:for-each select=".//interesting-tag[text()]"> 
     <xsl:value-of select="text()"/> 
    </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

Документ:

<?xml version="1.0"?> 
<?xml-stylesheet type="text/xsl" href="style.xslt"?> 
<root> 
    <foo> 
    <bar> 
     <interesting-tag> 
     Hello 
     </interesting-tag> 
     <interesting-tag> 
     World 
     </interesting-tag> 
    </bar> 
    <interesting-tag> 
     o11c was here 
    </interesting-tag> 
    </foo> 
</root> 
Смежные вопросы