#xslt
#xslt
Вопрос:
У меня есть следующий XML.
<?xml version="1.0" ?>
<Root xmlns="http://1.local/1.xsd">
<Definitions>
<FileTypes>
<FileType ID="1" Name="FileType1"/>
<FileType ID="2" Name="FileType2"/>
<!--... - lots of file types-->
<FileTypes>
</Definitions>
<Files>
<File Name="File1" FileTypeID="1" />
<File Name="File2" FileTypeID="1" />
<File Name="File3" FileTypeID="2" />
<!--... - lots of files-->
<Files>
</Root>
Для каждого файла мне нужно получить его атрибут Name и для его поиска FileTypeID соответствующее имя типа файла
Таким образом, примером вывода будет: Имя файла: File1 Тип файла: FileType1
Имя файла: File2 Тип файла: FileType1
Имя файла: File3 Тип файла: FileType2
Это XSLT, который у меня есть до сих пор, но я не уверен, как искать имя типа файла.
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:l="http://1.local/1.xsd"
exclude-result-prefixes="l"
version="1.0">
<xsl:output method="text" omit-xml-declaration="yes" media-type="text/plain" />
<xsl:template match="/">
<xsl:apply-templates select="l:Root/l:Files" />
</xsl:template>
<xsl:template match="l:Root/l:Files">
Why
<xsl:for-each select="l:File">
File name: <xsl:value-of select="@Name">
File type:
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Ответ №1:
Используйте xsl:key
здесь для поиска типов файлов
<xsl:key name="FileTypes" match="l:FileType" use="@ID" />
Затем, чтобы получить соответствующее имя типа файла, вы должны сделать это
<xsl:value-of select="key('FileTypes', @FileTypeID)/@Name" />
Попробуйте этот XSLT
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:l="http://1.local/1.xsd"
exclude-result-prefixes="l"
version="1.0">
<xsl:output method="text" omit-xml-declaration="yes" media-type="text/plain" />
<xsl:key name="FileTypes" match="l:FileType" use="@ID" />
<xsl:template match="/">
<xsl:apply-templates select="l:Root/l:Files" />
</xsl:template>
<xsl:template match="l:Files">
<xsl:for-each select="l:File">
File name: <xsl:value-of select="@Name" />
File type: <xsl:value-of select="key('FileTypes', @FileTypeID)/@Name" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
(Обратите внимание, что ваш XML неправильно сформирован, поскольку у вас нет правильных закрывающих тегов для FileTypes
и Files
.)
Ответ №2:
Если вы хотите работать с XSLT, вам нужно начать с понимания его языка выражений XPath для навигации по деревьям XML, вы можете выбрать //l:FileType[@ID = current()/@FileTypeID]/@Name
. Или в XSLT, как уже опубликовал Тим, вы можете использовать ключ для эффективной реализации поиска.
Ответ №3:
Вы можете попробовать следующий XSL.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:l="http://1.local/1.xsd"
exclude-result-prefixes="l"
version="1.0">
<xsl:output method="text" omit-xml-declaration="yes" media-type="text/plain" />
<xsl:template match="/">
<xsl:apply-templates select="l:Root/l:Files" />
</xsl:template>
<xsl:template match="l:Root/l:Files">
Why
<xsl:for-each select="l:File">
File name: <xsl:value-of select="@Name"/>
File type: <xsl:value-of select="//l:FileTypes/l:FileType[@ID=current()/@FileTypeID]/@Name"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Кроме того, вам нужно убедиться, что вы указали правильное пространство имен в своем преобразовании xsl, чтобы оно действительно соответствовало значениям в вашем XML, и вам не хватало нескольких закрывающих тегов в вашем XML.
Для полноты я включил фиксированный XML, который я использовал для решения
<Root xmlns="http://1.local/1.xsd">
<Definitions>
<FileTypes>
<FileType ID="1" Name="FileType1"/>
<FileType ID="2" Name="FileType2"/>
<!--... - lots of file types-->
</FileTypes>
</Definitions>
<Files>
<File Name="File1" FileTypeID="1" />
<File Name="File2" FileTypeID="1" />
<File Name="File3" FileTypeID="2" />
<!--... - lots of files-->
</Files>
</Root>
Комментарии:
1. Скорректировал это, чтобы отразить ответ Мартина, поскольку в переменной, которую я использовал, нет необходимости.