我有一个包含多个节点的XML,每个节点中都有相似的数据。我想从每个节点中删除一个特定属性(用户:IPADDRESS)。我已经了解了如何使用ors将多个元素链接在一起,只需省去User=“{@User}”匹配,这样它就不会出现在结果中:
XSL代码段:
<;xsl:template match=“创建|测试|分配|修改|修复|终止”>;
<;Creation CommitID=“{@CommitID}”Date=“{@Date}”BoardID=“{@BoardID}”>;
<;xsl:apply templates/>;
</创作>;
</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</木板画>;
<;装配图>;2010F</装配图>;
<;注释>;1959年</注释>;
</创作>;
<;测试委员会日期2007-12-10T10:39:43 BoardID=“1035”User=“CSAGAN:192.168.1.183”;
<;ElectricalTestData结果=“失败”版本=“IMM标准修订版”>;
<;AutomatedTest ReportVersion=“1.0”>;
<;测试设置>;
<;TestAppBuildDate>;2007年12月7日</TestAppBuildDate>;
<;版本路径>;c:\tests\versions\v12.txt</版本路径>;
<;版本号>;1.2</版本号>;
<;OperatorName>;萨根</OperatorName>;
<;StationID>;PC-191-NDGrasse</StationID>;
<;JigSN>;12345</JigSN>;
<;夹具装配>;42</夹具装配>;
<;TestStartTime>;2007-12-10 10:34:17</TestStartTime>;
</测试设置>;
</自动化测试>;
</电气测试数据>;
</测试>;
<;分配委员会=“1c1f”User=“JRandi:192.168.1.162”日期=“2008-09-30T07:36:52”董事会ID=“1035”>;
<;注释>;Boardset两次测试失败,未进行问题日志输入/修复尝试。</注释>;
</分配>;
<;修改委员会=“2bb7”User=“JRandi:192.168.1.162”日期=“2009-03-11T13:31:21”BoardID=“1035”>;
<;装配图>;2001G</装配图>;
<;注释>;Cornelius将boardset升级为rev。G</注释>;
</修改>;
</董事会数据>;
</董事会数据库>;
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/>;
</创作>;
</xsl:template>;
<;xsl:template match=“@*|node()”>;
<;xsl:copy>;
<;xsl:apply templates select=“@*|node()”/>;
</xsl:copy>;
</xsl:template>;
</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(,,':')”/>;
</xsl:attribute>;
</xsl:template>;
<;xsl:template match=“@*|node()”>;
<;xsl:copy>;
<;xsl:apply templates select=“@*|node()”/>;
</xsl:copy>;
</xsl:template>;
</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()|@*”/>;
</xsl:copy>;
</xsl:template>;
<;xsl:模板匹配=
*[包含(“|创建|测试|分配|修改|修复|终止|)”,concat(“|”,name(),“|”)
]/@用户“/>;
</xsl:stylesheet>;
尝试将模板更改为:
<;xsl:template match=“创建|测试|分配|修改|修复|终止”>;
<;xsl:copy>;
<;xsl:apply templates select=“@*[not(name()=“User”)]| node()”/>;
</xsl:copy>;
</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(,,':')”/>;
</xsl:attribute>;
</xsl:template>;