XSL - нужно что-то делать, когда text () это просто 'обычный текст' - PullRequest
1 голос
/ 03 мая 2011

Хотите выполнить некоторый анализ / модификацию текстового содержимого узла, если все, что text() возвращает, является чистой текстовой строкой.Нет XML внутри.

Например,

<test>some <super>1</super> text here</test>

text() для <test> возвращает только «некоторые».Это тот случай, когда я не хочу выводить текст и вместо этого хочу вызвать apply-templates.

Есть ли какой-либо способ сказать или эта ситуация слишком двусмысленна для XSL?

Редактировать: Мне нужен именно такой вывод

Причина заключается в следующем: иногда есть просто текст, в котором слово разделено на "/".Я хочу добавить пробелы до и после, так что вместо этого "/".Но иногда один и тот же узел содержит xML.

some <super>1</super> text here

Ответы [ 4 ]

2 голосов
/ 03 мая 2011

На самом деле в описанной ситуации text () возвращает последовательность из двух текстовых узлов, «some» и «text here», но в XSLT 1.0 многие операции над последовательностью (или набором) узлов игнорируют все узлы, кроме первый.

Вы не сказали, какой выход вы хотите. Но обычный способ обработки смешанного контента заключается в вызове apply-templates для обработки всех дочерних элементов. Явное использование text () очень редко правильно.

1 голос
/ 03 мая 2011

Вы можете проверить, есть ли у текущего узла дочерние элементы:

<xsl:template match="/test">
  <xsl:choose>
    <xsl:when test="./*">
      <xsl:text>children: </xsl:text>
      <xsl:apply-templates />
    </xsl:when>
    <xsl:otherwise>
        <xsl:text>just text: </xsl:text>
        <xsl:value-of select="./text()" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
1 голос
/ 03 мая 2011

Тест или предикат count(text()) = count(node()) должны работать, чтобы провести различие.

0 голосов
/ 03 мая 2011

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="vLetters"
    >qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM</xsl:variable>
    <xsl:variable name="vDots"
    >....................................................</xsl:variable>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="test/text()" name="tokenize">
        <xsl:param name="pString" select="string()"/>
        <xsl:variable name="vString"
         select="translate($pString,$vLetters,$vDots)"/>
        <xsl:choose>
            <xsl:when test="contains($vString,'./.')">
                <xsl:variable name="vOffset"
                 select="string-length(substring-before($vString,'./.'))"/>
                <xsl:value-of select="substring($pString,1,$vOffset+1)"/>
                <xsl:text> / </xsl:text>
                <xsl:call-template name="tokenize">
                    <xsl:with-param name="pString"
                     select="substring($pString,$vOffset+3)"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$pString"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

С этим входом:

<test>This is an answer/solution to <user>OP/bobber205</user>'s question/problem</test>

Выход:

<test>This is an answer / solution to <user>OP/bobber205</user>'s question / problem</test>

Примечание : в одну сторону (другой будет с модами) для разделения потомка следует использовать test//text() в качестве шаблона.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...