Как получить информацию и отсортировать подмножество элементов только с идентификаторами, используя XSLT?
Вопрос
Я новичок в XSLT, и я не могу решить следующую проблему:
У меня есть XML-файл, подобный этому:
<root>
<subset>
<e id="A"></e>
<e id="C"></e>
</subset>
<data>
<info id="A" order="3" name="ANode"></info>
<info id="B" order="4" name="BNode"></info>
<info id="C" order="1" name="CNode"></info>
<info id="D" order="2" name="DNode"></info>
</data>
</root>
И я хочу спродюсировать это:
<root>
<newnode id="C" order="1" name="CNode"></newnode>
<newnode id="A" order="3" name="ANode"></newnode>
</root>
Как вы можете видеть, идея состоит в том, чтобы "завершить" подмножество идентификаторов, извлекая соответствующую информацию, и отсортировать их соответственно их порядку, указанному на <data>
.
Обратите внимание , что <data>
предполагается, что у него много дочерних узлов.
Кроме того, я разделяю узлы с информацией о <data>
элемент из подмножеств идентификаторов, потому что у меня будет много подмножеств, и я не хочу иметь повторяющуюся информацию "везде".
Заранее благодарю.
Решение
Вы также можете отключить подмножество в зависимости от того, что еще вам может понадобиться сделать с вашими фактическими данными.
<xsl:output indent="yes" />
<xsl:key name="subset" match="e" use="@id" />
<xsl:template match="/">
<root>
<xsl:for-each select="//info[count(key('subset',@id)[1]) > 0]">
<xsl:sort select="@order" data-type="number" />
<newnode id="{@id}" order="{@order}" name="{@name}" />
</xsl:for-each>
</root>
</xsl:template>
Другие советы
Перекрестные ссылки запрашивают использование ключей:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:key name="k1" match="info" use="@id"/>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="subset/e">
<xsl:sort select="key('k1', @id)/@order" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="e">
<newnode id="{@id}" order="{key('k1', @id)/@order}" name="{key('k1', @id)/@name}"/>
</xsl:template>
</xsl:stylesheet>
Этого должно хватить для представленного вами входного образца.