如何将含多属性argument标签的XML转换为指定格式XML?
用XSLT直接实现XML日志到目标XML格式的转换
核心需求梳理
- 仅保留包含**type="reader"且id="27"**的
<argument>子节点的<event> - 从符合条件的
<event>中提取信息:- 将
<argument type="person">的@id值设为<lonetrans>的anstid属性 - 将
<argument type="floor_area">的@value值作为<lonart>的文本内容 - 将
<event>的毫秒级timestamp属性转换为日期格式,作为<datum>的文本内容
- 将
示例输入XML
<log> <event timestamp="1620000000000"> <argument type="reader" id="27"/> <argument type="person" id="P123"/> <argument type="floor_area" value="101.5"/> </event> <event timestamp="1620000100000"> <argument type="reader" id="28"/> <argument type="person" id="P456"/> <argument type="floor_area" value="202.3"/> </event> <event timestamp="1620000200000"> <argument type="reader" id="27"/> <argument type="person" id="P789"/> <argument type="floor_area" value="303.7"/> </event> </log>
XSLT转换代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" encoding="UTF-8"/> <!-- 匹配根节点,生成目标XML的根元素 --> <xsl:template match="/"> <root> <!-- 筛选符合条件的event:包含type为reader且id为27的argument --> <xsl:apply-templates select="log/event[argument[@type='reader' and @id='27']]"/> </root> </xsl:template> <!-- 处理符合条件的event节点 --> <xsl:template match="event"> <lonetrans anstid="{argument[@type='person']/@id}"> <!-- 用EXSLT日期函数转换毫秒时间戳为标准日期,需处理器支持 --> <datum> <xsl:value-of select="date:add('1970-01-01T00:00:00', concat(@timestamp div 1000, ' seconds'))" xmlns:date="http://exslt.org/dates-and-times"/> </datum> <lonart> <xsl:value-of select="argument[@type='floor_area']/@value"/> </lonart> </lonetrans> </xsl:template> <!-- 忽略其他不匹配的节点 --> <xsl:template match="text()|@*"/> </xsl:stylesheet>
兼容性调整
如果你的XSLT处理器不支持EXSLT,可改用XSLT 2.0+原生日期处理,只需修改<datum>部分的代码,并升级XSLT版本:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- 其他模板不变,仅修改datum节点 --> <xsl:template match="event"> <lonetrans anstid="{argument[@type='person']/@id}"> <datum> <xsl:value-of select="xs:dateTime('1970-01-01T00:00:00') + xs:dayTimeDuration(concat(@timestamp div 1000, 'S'))"/> </datum> <lonart> <xsl:value-of select="argument[@type='floor_area']/@value"/> </lonart> </lonetrans> </xsl:template> </xsl:stylesheet>
示例输出XML
<?xml version="1.0" encoding="UTF-8"?> <root> <lonetrans anstid="P123"> <datum>2021-05-03T13:20:00</datum> <lonart>101.5</lonart> </lonetrans> <lonetrans anstid="P789"> <datum>2021-05-03T13:23:20</datum> <lonart>303.7</lonart> </lonetrans> </root>
内容的提问来源于stack exchange,提问作者AndersG
相关产品推荐
相关产品推荐

