用于合并2个节点的XSL/XSLT/XPath
我有一些包含记录用于合并2个节点的XSL/XSLT/XPath,xslt,xpath,Xslt,Xpath,我有一些包含记录文件路径和文件名的节点的XML。我需要一个XSLT将它们转换为FilePathAndName的单个节点。文件路径值可能以“\”结尾,也可能不以“\”结尾。任何值都可以为空。FilePathAndName值必须以'\'结尾,如果它只是一个文件夹名 转换将从C#应用程序调用,因此我想我可能可以使用任何版本的XSLT 我已经做了一部分,但正在努力完成完整的解决方案,包括在输入中考虑可选的'\'值 以下是一些示例输入XML: <Task> <Action Act
文件路径
和文件名
的节点的XML。我需要一个XSLT
将它们转换为FilePathAndName
的单个节点。文件路径
值可能以“\”结尾,也可能不以“\”结尾。任何值都可以为空。FilePathAndName
值必须以'\'结尾,如果它只是一个文件夹名
转换将从C#应用程序调用,因此我想我可能可以使用任何版本的XSLT
我已经做了一部分,但正在努力完成完整的解决方案,包括在输入中考虑可选的'\'值
以下是一些示例输入XML:
<Task>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePath" ParameterValue="folder1\sub-folder1" /> <!-- FilePath doesn't end in '\' -->
<Parameter ParameterName="FileName" ParameterValue="file1" />
</Action>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePath" ParameterValue="folder2\sub-folder2\" /> <!-- FilePath ends in '\' -->
<Parameter ParameterName="FileName" ParameterValue="file2" />
</Action>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePath" ParameterValue="" /> <!-- Empty FilePath -->
<Parameter ParameterName="FileName" ParameterValue="file3" />
</Action>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePath" ParameterValue="folder4\sub-folder4" /> <!-- Empty FileName -->
<Parameter ParameterName="FileName" ParameterValue="" />
</Action>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePath" ParameterValue="" /> <!-- Empty FilePath and FileName -->
<Parameter ParameterName="FileName" ParameterValue="" />
</Action>
<Action ActionName="GetRateData">
<!-- No FilePath Node -->
<Parameter ParameterName="FileName" ParameterValue="file5" />
</Action>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePath" ParameterValue="folder6\sub-folder6" />
<!-- No FileName Node -->
</Action>
<Action ActionName="GetRateData">
<!-- No FilePath or FileName Node -->
</Action>
</Task>
应将其转换为以下内容:
<Task>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePathAndName" ParameterValue="folder1\sub-folder1\file1" />
</Action>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePathAndName" ParameterValue="folder2\sub-folder2\file2" />
</Action>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePathAndName" ParameterValue="file3" />
</Action>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePathAndName" ParameterValue="folder4\sub-folder4\" />
</Action>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePathAndName" ParameterValue="" />
</Action>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePathAndName" ParameterValue="file5" />
</Action>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePathAndName" ParameterValue="folder6\sub-folder6\"/>
</Action>
<Action ActionName="GetRateData">
<Parameter ParameterName="FilePathAndName" ParameterValue="" />
</Action>
</Task>
这是我尝试的解决方案:
<xsl:template match="Task">
<Task>
<xsl:for-each select="Action">
<Action>
<xsl:copy-of select="@ActionName"/>
<xsl:for-each select="Parameter">
<Parameter>
<xsl:choose>
<xsl:when test="@ParameterName = 'FilePath'">
<xsl:attribute name="ParameterName">
<xsl:text>FilePathAndName</xsl:text>
</xsl:attribute>
<xsl:attribute name="ParameterValue">
<xsl:value-of select="@ParameterValue" />\<xsl:value-of select="(../Parameter[@ParameterName='FileName'])[1]/@ParameterValue" /></xsl:attribute>
<!-- TODO: Don't include '\' if FilePath is empty. -->
<!-- TODO: What if FilePath is missing? -->
</xsl:when>
<xsl:when test="@ParameterName = 'FileName'">
<!-- FileName will be consumed above. -->
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="@ParameterName"/>
<xsl:copy-of select="@ParameterValue"/>
</xsl:otherwise>
</xsl:choose>
</Parameter>
</xsl:for-each>
</Action>
</xsl:for-each>
</Task>
</xsl:template>
</xsl:stylesheet>
文件路径和名称
\
这将产生以下结果(其余问题请参见下面的XML注释):
如果您可以使用XSLT2.0,那么您可以这样做
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Action">
<xsl:copy>
<xsl:copy-of select="@*" />
<Parameter FileNameAndPath="{replace(Parameter[@ParameterName='FilePath']/@ParameterValue, '([^\\])$', '$1\\')}{Parameter[@ParameterName='FileName']/@ParameterValue}" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请你展示一下你的半路尝试,因为你可能离解决方案不远了!另外,您能否说您是否可以使用XSLT2.0或更高版本?非常感谢。太棒了,谢谢!XSL和XPath的内容显然比我从我读过的这本小书中得到的要多。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Action">
<xsl:copy>
<xsl:copy-of select="@*" />
<Parameter FileNameAndPath="{replace(Parameter[@ParameterName='FilePath']/@ParameterValue, '([^\\])$', '$1\\')}{Parameter[@ParameterName='FileName']/@ParameterValue}" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Action">
<xsl:copy>
<xsl:copy-of select="@*" />
<Parameter>
<xsl:attribute name="FileNameAndPath">
<xsl:variable name="FilePath" select="Parameter[@ParameterName='FilePath']/@ParameterValue" />
<xsl:value-of select="$FilePath" />
<xsl:if test="$FilePath != '' and substring($FilePath, string-length($FilePath)) != '\'">\</xsl:if>
<xsl:value-of select="Parameter[@ParameterName='FileName']/@ParameterValue" />
</xsl:attribute>
</Parameter>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>