Подтвердить что ты не робот

Разница между: child:: node() и child:: *

Я просто написал XSLT, который сначала не работал.

Мне пришлось переименовать всех детей <Recordset> в <C>:

<?xml version="1.0" encoding="utf-8"?>
<Record>
<Recordset>
    <company>102</company>
    <store>1801</store>
    ....
</Recordset>
<Recordset>
....
</Recordset>
</Record>

Я использовал следующий XSLT:

<xsl:template match="Record/Recordset/child::*">    
    <xsl:element name="C">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

Он работает и переименовывает всех дочерних элементов <Recordset> в <C>. Но сначала мой матч в шаблоне выглядел так:

<xsl:template match="Record/Recordset/child::node()">

Моя идея заключалась в том, что каждый дочерний элемент <Recordset> является node, поэтому node() будет уместным. Он тоже работал, но для каждого ребенка добавлен дополнительный <C/>.

Какая разница между child::node() и child::*?

4b9b3361

Ответ 1

child::node() соответствует любому node, который не является атрибутом node, namespace node или документом node. Это означает, что оно соответствует командам обработки, комментариям и текстовым узлам.

child::* соответствует только элементам.

См. раздел 5.5.3 спецификации:

Образец node() соответствует всем узлам выбранный выражением root (.)//(child-or-top:: node()), что есть, все элементы, текст, комментарий и обрабатывать узлы команд, независимо от того, или нет, у них есть родитель. Это не атрибут соответствия или узлы пространства имен потому что выражение не выбирает узлы, использующие атрибут или пространство имен Оси. Он не соответствует узлам документа потому что для обратной совместимости причины, по которым ось "ребенок-верх" не сопоставить документ node.

Обновление: Майкл ответил вдохновил следующую таблицу стилей. Используйте его для проверки типов узлов по мере их обработки:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/|node()">
        <xsl:call-template name="type" />
        <xsl:text>  [  </xsl:text>
        <xsl:value-of select="." />
        <xsl:text>&#10;</xsl:text>
        <xsl:apply-templates select="node()" />
        <xsl:text>  ]  </xsl:text>
    </xsl:template>
    <xsl:template name="type">
        <xsl:choose>
            <xsl:when test="count(.|/)=1">
                <xsl:text>Root</xsl:text>
            </xsl:when>
            <xsl:when test="self::*">
                <xsl:text>Element </xsl:text>
                <xsl:value-of select="name()" />
            </xsl:when>
            <xsl:when test="self::text()">
                <xsl:text>Text</xsl:text>
            </xsl:when>
            <xsl:when test="self::comment()">
                <xsl:text>Comment</xsl:text>
            </xsl:when>
            <xsl:when test="self::processing-instruction()">
                <xsl:text>PI</xsl:text>
            </xsl:when>
            <xsl:when test="count(.|../@*)=count(../@*)">
                <xsl:text>Attribute</xsl:text>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

Измените, что соответствовало/выбрано для проверки других шаблонов. Например, следующий ввод:

<A attr="test" other="val">
  <B/>
  <C>some value</C>
  <!-- a comment -->
  <D/>
</A>

Производит следующий вывод:

Root  [  

  some value



Element A  [  

  some value



Text  [  

  ]  Element B  [  
  ]  Text  [  

  ]  Element C  [  some value
Text  [  some value
  ]    ]  Text  [  

  ]  Comment  [   a comment 
  ]  Text  [  

  ]  Element D  [  
  ]  Text  [  

  ]    ]    ]  

Особая благодарность этой странице за то, что вы начали работу с тестами node. (Это особенно подходит, что один из ответов Майкла из более чем шести лет назад тоже появляется там.)

Ответ 2

Чтобы расширить ответ на lwburk, если ваш XML выглядит так:

<A>
  <B/>
  <C/>
  <D/>
</A>

Тогда элемент A имеет 7 дочерних узлов; три из них - это элементы, четыре - текстовые узлы. Выражение child::node() соответствует всем 7, тогда как child::* соответствует только элементам.