XSLT:使用多个或多个模板匹配来应用模板

我有一个包含多个节点的XML,每个节点中都有相似的数据。我想从每个节点中删除一个特定属性(用户:IPADDRESS)。我已经了解了如何使用ors将多个元素链接在一起,只需省去User=“{@User}”匹配,这样它就不会出现在结果中:

XSL代码段:

<xsl:template match=“创建|测试|分配|修改|修复|终止”>
<Creation CommitID=“{@CommitID}”Date=“{@Date}”BoardID=“{@BoardID}”>
<xsl:apply templates/>
&lt/创作>
&lt/xsl:template>

毫不奇怪,“Creation”之后的所有节点名都被重新命名为Creation,因为这就是我告诉它要做的。如何传递各种匹配,以便在结果中以正确的顺序应用它们?我知道我可以对每个不同的匹配使用相同的XSL语句(这是我第一次这样做的),但肯定有一种更优雅的方法,它只是在回避我。我有几百万;要处理数百万行XML,这只是我将要进行的许多转换中的第一个

我在Win7机器上使用msxsl V4.0进行转换,如果这样做有任何后果的话

XML:

<?xml version=“1.0”?>
<董事会数据库>
<线路板数据线路板ID=“1035”>
<创建委员会日期2007-12-07T15:43:51 BoardID=“1035”User=“CSAGAN:192.168.1.177”>
<木板画>3B&lt/木板画>
<装配图>2010F&lt/装配图>
<注释>1959年&lt/注释>
&lt/创作>
<测试委员会日期2007-12-10T10:39:43 BoardID=“1035”User=“CSAGAN:192.168.1.183”;
<ElectricalTestData结果=“失败”版本=“IMM标准修订版”>
<AutomatedTest ReportVersion=“1.0”>
<测试设置>
<TestAppBuildDate>2007年12月7日&lt/TestAppBuildDate>
<版本路径>c:\tests\versions\v12.txt&lt/版本路径>
<版本号>1.2&lt/版本号>
<OperatorName>萨根&lt/OperatorName>
<StationID>PC-191-NDGrasse&lt/StationID>
<JigSN>12345&lt/JigSN>
<夹具装配>42&lt/夹具装配>
<TestStartTime>2007-12-10 10:34:17&lt/TestStartTime>
&lt/测试设置>
&lt/自动化测试>
&lt/电气测试数据>
&lt/测试>
<分配委员会=“1c1f”User=“JRandi:192.168.1.162”日期=“2008-09-30T07:36:52”董事会ID=“1035”>
<注释>Boardset两次测试失败,未进行问题日志输入/修复尝试。&lt/注释>
&lt/分配>
<修改委员会=“2bb7”User=“JRandi:192.168.1.162”日期=“2009-03-11T13:31:21”BoardID=“1035”>
<装配图>2001G&lt/装配图>
<注释>Cornelius将boardset升级为rev。G&lt/注释>
&lt/修改>
&lt/董事会数据>
&lt/董事会数据库>

XSL:

<xsl:stylesheet xmlns:xsl=”http://www.w3.org/1999/XSL/Transform“version=“1.0”>
<xsl:template match=“创建|测试|分配|修改|修复|终止”>
<Creation CommitID=“{@CommitID}”Date=“{@Date}”BoardID=“{@BoardID}”>
<xsl:apply templates/>
&lt/创作>
&lt/xsl:template>
<xsl:template match=“@*|node()”>
<xsl:copy>
<xsl:apply templates select=“@*|node()”/>
&lt/xsl:copy>
&lt/xsl:template>
&lt/xsl:stylesheet>

使用@DevNull解决方案的最新XSL,该解决方案将原始文件的大小增加了一倍:

<xsl:stylesheet xmlns:xsl=”http://www.w3.org/1999/XSL/Transform“version=“1.0”>
<!--来自堆栈溢出的答案,该堆栈溢出仅从用户属性中删除IP地址--&燃气轮机;
<xsl:template match=“@User”>
<xsl:attribute name=“User”>
<xsl:select=“substring before(,,':')”/>
&lt/xsl:attribute>
&lt/xsl:template>
<xsl:template match=“@*|node()”>
<xsl:copy>
<xsl:apply templates select=“@*|node()”/>
&lt/xsl:copy>
&lt/xsl:template>
&lt/xsl:stylesheet>

@Dimitre解决方案中的最新XSL需要很长时间才能处理(30分钟后仍在运行,但文件仍在增长):

<xsl:stylesheet version=“1.0”xmlns:xsl=”http://www.w3.org/1999/XSL/Transform“>
<xsl:output-omit-xml-declaration=“yes”indent=“yes”/gt;
<xsl:strip space elements=“*”/>
<xsl:template match=“node()|@*”>
<xsl:copy>
<xsl:apply templates select=“node()|@*”/>
&lt/xsl:copy>
&lt/xsl:template>
<xsl:模板匹配=
*[包含(“|创建|测试|分配|修改|修复|终止|)”,concat(“|”,name(),“|”)
]/@用户“/>
&lt/xsl:stylesheet>

尝试将模板更改为:

<xsl:template match=“创建|测试|分配|修改|修复|终止”>
<xsl:copy>
<xsl:apply templates select=“@*[not(name()=“User”)]| node()”/>
&lt/xsl:copy>
&lt/xsl:template>

您会注意到它看起来非常像您的标识模板,在@*中添加了一个谓词

此外,如果您想去除所有User属性,而不管元素是什么,您可以使用此模板:

<xsl:template match=“@User”/>

这里还有一种方法(为了简洁起见,仅从创建测试中剥离)

<xsl:template match=“@User[..[self::Creation或self::Test]]”/>

回复评论

请改用此模板:

<xsl:template match=“@User”>
<xsl:attribute name=“User”>
<xsl:select=“substring before(,,':')”/>
&lt/xsl:attribute>
&lt/xsl:template>

发表评论