使用xsl将xml转换为纯文本,无需硬编码
我已经使用xsl将XML转换为纯文本,我想输出节点的文本和属性。我希望xsl是通用的,不包含节点的名称。我设法做到了。但是当我有一个xml中的空节点时,它将被写入输出中。我不想那样。如何停止使用xsl写入空节点或属性?我正在寻找一种实现,它不检查节点的名称,而是检查所有节点 我有以下XML使用xsl将xml转换为纯文本,无需硬编码,xml,xslt,Xml,Xslt,我已经使用xsl将XML转换为纯文本,我想输出节点的文本和属性。我希望xsl是通用的,不包含节点的名称。我设法做到了。但是当我有一个xml中的空节点时,它将被写入输出中。我不想那样。如何停止使用xsl写入空节点或属性?我正在寻找一种实现,它不检查节点的名称,而是检查所有节点 我有以下XML <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <run xmlns:xsi="http://www.w3.org/2001/
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<run xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tests>
<test name="a" attr1="" attr2="" attr3="an_value">
<usecase name="name1">
<description>Some description</description>
</usecase>
<usecase name="name2">
<description>Descripton1</description>
</usecase>
<usecase name="name3">
<description>Descripton2</description>
</usecase>
</test>
</tests>
<vip>
<file name="b">
<stat wins="1"/>
<justifications/>
</file>
<file name="c">
<stat wins="2" />
<justifications/>
</file>
</vip>
</run>
如果没有硬编码xsl,我可以使用什么xsl命令不显示节点对正以及属性attr1和attr2(如果它们都为空)
期望输出
run
tests
test name : a attr3 : an_value
usecase name : name1
description Some description
usecase name : name2
description Descripton1
usecase name : name3
description Descripton2
vip
file name : b
stat wins : 1
file name : c
stat wins : 2
编辑:
我将xsl更新为
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no"/>
<xsl:variable name="empty_string" select="''" />
<xsl:strip-space elements="*"/>
<xsl:template match="node()">
<xsl:value-of select="local-name()"/>
<xsl:text> </xsl:text>
<xsl:value-of select="text()" />
<xsl:call-template name="attributes"/>
<xsl:text>
</xsl:text>
<xsl:apply-templates select=" node()"/>
</xsl:template>
<xsl:template name="attributes">
<xsl:for-each select="@*">
<xsl:if test="normalize-space(.) != $empty_string">
<xsl:value-of select="local-name()"/>
<xsl:text> : </xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
:
我仍然在寻找一个条件,如果节点没有属性和子节点,就不写它。在这种情况下,将不显示对齐节点。该示例有点含糊不清,此处需要应用的逻辑也不完全清楚。我猜你想做一些类似的事情: XSLT1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*[@*|node()]">
<xsl:value-of select="name()"/>
<xsl:text> </xsl:text>
<xsl:apply-templates select="@*[string()]|text()"/>
<xsl:text> </xsl:text>
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="@*">
<xsl:value-of select="name()"/>
<xsl:text> : </xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
:
就个人而言,我不会使用空格作为分隔符,因为它可以很容易地显示为值的一部分(实际上,换行符也是如此)。以下是一种方法:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text"/>
<xsl:template match="node()">
<xsl:if test="text() or node() or @*">
<xsl:text>
</xsl:text>
<xsl:value-of select="local-name()"/>
<xsl:text> </xsl:text>
<xsl:value-of select="normalize-space(text())"/>
</xsl:if>
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="@*">
<xsl:if test=".!=''">
<xsl:value-of select="local-name()"/>
<xsl:text> : </xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
</xsl:stylesheet>
;
:
查看此处的工作情况:文本值的结果应该是什么?类似于:test attr2:attr value为什么应该排除
“text value”
?我的问题。不应排除任何内容,仅当属性为空且节点没有子项或属性时才应使用排除,在其余情况下,我们提取所有数据。test attr2:attr value text value类似于此。此示例仅用于测试。其思想是,它可以是具有任何模式的xml,只有节点和属性中的数据才能复制为纯文本。空格部分是因为最初情况更糟。使用您的解决方案,不再写入空属性,这比我最初的解决方案有了很大的改进。我尝试了您的解决方案,但您丢失了描述,空对正节点仍然存在。@BlajBogdan我更新了我的答案,它现在应该符合您的需要。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*[@*|node()]">
<xsl:value-of select="name()"/>
<xsl:text> </xsl:text>
<xsl:apply-templates select="@*[string()]|text()"/>
<xsl:text> </xsl:text>
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="@*">
<xsl:value-of select="name()"/>
<xsl:text> : </xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text"/>
<xsl:template match="node()">
<xsl:if test="text() or node() or @*">
<xsl:text>
</xsl:text>
<xsl:value-of select="local-name()"/>
<xsl:text> </xsl:text>
<xsl:value-of select="normalize-space(text())"/>
</xsl:if>
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="@*">
<xsl:if test=".!=''">
<xsl:value-of select="local-name()"/>
<xsl:text> : </xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
</xsl:stylesheet>