#xslt #dynamic #msxsl #node-set
#xslt #динамический #msxsl #набор узлов
Вопрос:
Я хотел бы знать, возможно ли вложить динамические наборы узлов в XSLT, и если да, то как их выбрать с помощью XPath. Это часть более масштабной задачи. Я показываю только ту часть, на которой я застрял.
Это мой XSLT:
<xsl:variable name="Tables">
<xsl:for-each select="Table">
<xsl:variable name="TableName" select="Name | @Name"/>
<xsl:variable name="Columns">
<xsl:for-each select="Column">
<xsl:variable name="ColumnName" select="Name | @Name"/>
<xsl:variable name="Type" select="Type | @Type"/>
<Column>
<Name>
<xsl:value-of select="$ColumnName"/>
</Name>
<Type>
<xsl:value-of select="$Type"/>
</Type>
</Column>
</xsl:for-each>
</xsl:variable>
<Table>
<Name>
<xsl:value-of select="$TableName"/>
</Name>
<Columns>
<xsl:value-of select="$Columns"/>
</Columns>
</Table>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="msxsl:node-set($Tables)/Table">
Table Name: <xsl:value-of select="Name"/>
<xsl:for-each select="msxsl:node-set(Columns)/Column" xml:space="preserve">
Column Name: <xsl:value-of select="Name"/>
Column Type: <xsl:value-of select="Type"/>
</xsl:for-each>
</xsl:for-each>
Это мой XML:
<Table Name="Product">
<Column Name="ProductID" Type="int"/>
<Column Name="Name" Type="string"/>
<Column Name="Cost" Type="decimal"/>
<Column Name="Area" Type="decimal?"/>
</Table>
<Table Name="Market">
<Column Name="MarketID" Type="int"/>
<Column Name="Name" Type="string"/>
<Column Name="MinimumASP" Type="double"/>
<Column Name="MaximumASP" Type="double"/>
</Table>
Это результат, который я получаю в данный момент:
Table Name: Product
Table Name: Market
Это то, что я хотел бы получить:
Table Name: Product
Column Name: ProductID
Column Type: int
Column Name: Name
Column Type: string
Column Name: Cost
Column Type: decimal
Column Name: Area
Column Type: decimal?
Table Name: Market
Column Name: MarketID
Column Type: int
Column Name: Name
Column Type: string
Column Name: MinimumASP
Column Type: double
Column Name: MaximumASP
Column Type: double
Комментарии:
1. @user708613: Есть две ошибки: вы должны использовать
<xsl:copy-of select="$Columns"/>
вместо<xsl:value-of select="$Columns"/>
;$Columns
выходит за рамки этих самых внешнихxsl:for-each
инструкций. Вы должны использоватьmsxsl:node-set($Table)/Table/Columns/Column
.2. Мне просто нужно было изменить значение-of на copy-of, и это работает! Большое спасибо!
3. Хороший вопрос, 1. Смотрите мой ответ для полного, короткого и простого решения, которое не создает никаких временных деревьев и вообще не нуждается в
xxx:node-set()
функции.
Ответ №1:
Желаемый результат может быть получен im гораздо более простым способом, и нет необходимости создавать какие-либо временные деревья:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*/*">
<xsl:apply-templates select="@*|*"/>
</xsl:template>
<xsl:template match="@*">
<xsl:value-of select=
"concat(name(..), ' ', name(), ': ', .)"/>
<xsl:text>amp;#xA;</xsl:text>
</xsl:template>
</xsl:stylesheet>
Когда это преобразование применяется к предоставленному XML-документу (заключенному в один верхний элемент, чтобы сделать его правильно сформированным):
<t>
<Table Name="Product">
<Column Name="ProductID" Type="int"/>
<Column Name="Name" Type="string"/>
<Column Name="Cost" Type="decimal"/>
<Column Name="Area" Type="decimal?"/>
</Table>
<Table Name="Market">
<Column Name="MarketID" Type="int"/>
<Column Name="Name" Type="string"/>
<Column Name="MinimumASP" Type="double"/>
<Column Name="MaximumASP" Type="double"/>
</Table>
</t>
получен желаемый, правильный результат:
Table Name: Product
Column Name: ProductID
Column Type: int
Column Name: Name
Column Type: string
Column Name: Cost
Column Type: decimal
Column Name: Area
Column Type: decimal?
Table Name: Market
Column Name: MarketID
Column Type: int
Column Name: Name
Column Type: string
Column Name: MinimumASP
Column Type: double
Column Name: MaximumASP
Column Type: double
Комментарии:
1. Это часть более масштабной задачи, и мне нужны деревья для других целей. Но спасибо — я немного научился, посмотрев на ваше решение.