Я собираю XSL вместе, чем создам скрипт сборки NAnt, используя в качестве входных данных XML-файл, который определяет все элементы, которые должны быть собраны. У нас есть много очень похожих проектов со стандартными макетами и определенными стандартами для областей хэндовера, и поэтому наличие файла XML, который определяет, чего хотят разработчики, а не описывает, как это должно быть сделано, очень помогло бы освоению сервиса сборки.
Я хочу заранее определить в XML-файле сборки продукта используемые режимы сборки, т. Е.
<Build>
<BuildModes>
<Mode name="Debug" />
<Mode name="Release" />
</BuildModes>
<ItemsToBuild>
<Item name="first item" .... />
<Item name="second item" .... />
</ItemsToBuild>
</Build>
Я хочу иметь
<xsl:for-each select="/Build/BuildModes/Mode">
<xsl:for-each select="/Build/ItemsToBuild/Item">
<exec program="devenv">
<xsl:attribute name="line">
use the @name from the Mode and other stuff from Item to build up the command line
</xsl:attribute>
</xsl:for-each>
</xsl:for-each>
Теперь я могу сделать это, задав между двумя строками for-each значение, определенное для значения Mode / @ name, но это немного запутанно, и я действительно хочу перевернуть nexting так, чтобы сборка mode находится внутри цикла Item, поэтому он создает один режим, а затем другой. На данный момент он собрал бы все отладки, а затем все сборки выпуска. Чтобы сделать это, мне нужно было бы объявить несколько, и это становится очень грязным.
Так что он вложен, когда элементы в исходном документе не вложены.
EDIT:
хорошо, поскольку принятый ответ ниже показывает, что использование for-each является плохой идеей в большинстве случаев, и я переделал этот пример в следующий. Это немного отличается, поскольку схема, которую я использую, была упрощена для вышеупомянутого поста, но вы поняли идею.
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/>
<xsl:template match="/BuildDefinition">
<xsl:apply-templates select="/BuildDefinition/VS2008SLN/DeploymentProject"/>
</xsl:template>
<xsl:template match="/BuildDefinition/VS2008SLN/DeploymentProject">
<xsl:apply-templates select="/BuildDefinition/BuildModes/Mode">
<xsl:with-param name="BuildTarget" select="." />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="/BuildDefinition/BuildModes/Mode">
<xsl:param name="BuildTarget" />
<exec program="devenv"> <!-- not the real call, but for example purposes -->
<xsl:attribute name="ProjectName" select="$BuildTarget/@ProjectName"/>
<xsl:attribute name="SolutionName" select="$BuildTarget/../@SolutionName" />
<xsl:attribute name="ModeName" select="@name"/>
</exec>
</xsl:template>
</xsl:stylesheet>
и это схема, к которой он работает
<BuildDefinition Version="1.0">
<BuildModes>
<Mode name="Debug" />
<Mode name="Release" />
</BuildModes>
<VS2008SLN
SolutionName="MySolution"
SolutionDirectory="Visual Studio 2008\MySolution">
<DeploymentProject
ProjectName="MyDeploymentProject"
DeploymentTargetDirectory="EndsUpHere"
DeploymentManifestName="AndCalledThisInTheDocumentation" />
</VS2008SLN>