gpt4 book ai didi

xslt - 搜索祖先或 self 轴以找到第一个非空属性值

转载 作者:行者123 更新时间:2023-12-03 16:53:24 25 4
gpt4 key购买 nike

在使用 WireShark 的 pdml 输出(此处定义:http://www.nbee.org/doku.php?id=netpdl:pdml_specification)时,我试图将下面相同结构的较大文档转换为下面的示例:

原始 XML:

<packet>
<proto name="geninfo" pos="0" showname="General Information" size="308">
<field name="num" pos="0" show="2574" showname="Number" value="a0e" size="308"/>
<!-- more field tags here -->
</proto>
<proto name="ip" showname="Internet Protocol Version 4" size="0" pos="0">
<field name="" show="This is a fake entry created from the metadata" size="308" pos="0" value="">
<field name="ip.src" showname="Source: 1.2.3.4 (1.2.3.4)" size="0" pos="0" show="1.2.3.4"/>
<field name="ip.src2" showname="Source: 1.2.3.4 (1.2.3.4)" hide="yes" size="0" pos="0" show="1.2.3.4"/>
<!-- more field tags here -->
</field>
<!-- more field tags here -->
</proto>
<!-- more proto tags here -->
</packet>

预期/有希望/最终输出:
<packet>
<geninfo>
<pos>0</pos>
<showname>General Information</showname>
<size>308</size>
<num>
<pos>0</pos>
<show>2574</show>
<showname>Number</showname>
<value>a0e</value>
<size>308</size>
</num>
<!-- more transformed field tags here -->
</geninfo>
<ip>
<showname>Internet Protocol Version 4</showname>
<size>0</size>
<pos>0</pos>
<ip>
<show>This is a fake entry created from the metadata</show>
<size>308</size>
<pos>0</pos>
<ip.src>
<showname>Source: 1.2.3.4 (1.2.3.4)</showname>
<size>0</size>
<pos>0</pos>
<show>1.2.3.4</show>
</ip.src>
<!-- more transformed field tags here -->
</ip>
<!-- more transformed field tags here -->
</ip>
<!-- more transformed proto tags here -->
</packet>

当前 XSLT:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/transform" version="1.0">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="*[not(@hide)]">
<xsl:variable name="nameAttr" select="ancestor-or-self::*[@name][1]/@name!=''"/>
<xsl:element name="{$nameAttr}">
<xsl:for-each select="@*[name(.)!='name' and .!='']">
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xst:template>
</xsl:stylesheet>

这将跳过所有具有隐藏属性的标签,并将剩余标签的非名称属性移动到使用名称属性值创建的新元素的子标签,同时跳过具有空字符串值的非名称属性。在名称属性值为空字符串的情况下,我打算使用祖先或自我轴来查找第一个非空名称属性值,递归地搜索祖先,知道每个 proto 标记都将具有非空名称属性值,如果搜索到了那么远。

任何有关获取第一个祖先或自我非空属性名称值的语法帮助(它当前返回是否 @name != '' 的 bool 值)和任何 xslt 风格/良好实践评论都表示赞赏。

最佳答案

在处理你所拥有的东西时,我想出了这个:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes" />

<xsl:template match="/packet">
<packet>
<xsl:apply-templates />
</packet>
</xsl:template>

<xsl:template match="proto[not(@hide)]">
<xsl:element name="{@name}">
<xsl:apply-templates select="*|@*" />
</xsl:element>
</xsl:template>

<xsl:template match="field[@name != '']">
<xsl:element name="{@name}">
<xsl:apply-templates select="*|@*" />
</xsl:element>
</xsl:template>

<xsl:template match="field[@name = '']">
<xsl:element name="{ancestor::*[@name != ''][1]/@name}">
<xsl:apply-templates select="*|@*" />
</xsl:element>
</xsl:template>

<xsl:template match="@*[name() != 'name']">
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>

</xsl:stylesheet>

与您的原始问题相关,这是获取具有非空@name 的祖先的 XPath:
<xsl:element name="{ancestor::*[@name != ''][1]/@name}">

但是您确实需要进行一些重组以使这项工作以可维护的方式工作 - 尝试使用模板而不是 for-each 循环来思考 - 它将为您提供更加模块化和灵活的设计。在上面的样式表中,有一个模板来匹配根节点(/packet)、没有隐藏属性的原型(prototype)节点、具有填充名称的字段节点、没有的字段节点以及没有的属性t 一个“名称”属性。

关于xslt - 搜索祖先或 self 轴以找到第一个非空属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31925078/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com