我必须重新创建一个新的xml,其中包含来自' old'的标签名称和值。 xml使用xslt 1.0。
我的问题是,即使没有值放在标签之间,它也会生成空标签。
有没有办法在转换结束时摆脱那些空标签?
我知道你可以做for-each循环并做类似的事情,但问题是我需要进行多次转换,这是不可取的:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"*[not(node())]
|
*[not(node()[2])
and
node()/self::text()
and
not(normalize-space())
]
"/>
</xsl:stylesheet>
示例xml输入:
<root>
<address1>
<line1>line1address1<line1>
<line2>line2address1<line2>
<line3>line3address1<line3>
</address1>
<address2>
<line1/>
<line2/>
<line3/>
</address2>
<address3 />
<address4>
<line1>line1address4<line1>
<line2>line2address4<line2>
<line3/>
</address4>
</root>
示例xml输出:
<root>
<homeAddress>
<street>line1address1<street>
<number>line2address1<number>
<postcode>line3address1<postcode>
<homeAddress>
<workAdddress>
<street>line1address4<street>
<number>line2address4<number>
</workAdddress>
</root>
这里的示例xml不是我正在使用的实际xml,所以不要担心它没有很好地形成。
所有答案似乎都在使用复制标签,而有人说我的标签与输入xml不匹配 - 这正是我为什么要这样做的原因,我不能做简单的复制并将所有空元素与创建的模板相匹配没有。我需要做的是创建具有不同名称的新标签,并从输入xml中输入不同名称标签的值。希望这会对此有所了解,我仍然在努力解决这个问题并且不确定如何解决这个问题。
答案 0 :(得分:1)
这是我到目前为止所做的实验。不完整,但这可以给你一个方向:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output media-type="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="@*[not(text()='')]|node()[not(text()='')]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
测试了以下XML:
<?xml version="1.0" encoding="UTF-8"?>
<document>
<element1>TEST1</element1>
<element2>TEST2</element2>
<element3/>
<element4>TEST4</element4>
</document>
结束于:
TEST1 TEST2 TEST4
答案 1 :(得分:0)
你有一个不会被处理的例子:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(node())]"/>
</xsl:stylesheet>
答案 2 :(得分:0)
这与@ michael.hor257k的答案类似,但也会删除address2
XML输入
<root>
<address1>
<line1>line1address1</line1>
<line2>line2address1</line2>
<line3>line3address1</line3>
</address1>
<address2>
<line1/>
<line2/>
<line3/>
</address2>
<address3/>
<address4>
<line1>line1address4</line1>
<line2>line2address4</line2>
<line3/>
</address4>
</root>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(string())]"/>
</xsl:stylesheet>
XML输出
<root>
<address1>
<line1>line1address1</line1>
<line2>line2address1</line2>
<line3>line3address1</line3>
</address1>
<address4>
<line1>line1address4</line1>
<line2>line2address4</line2>
</address4>
</root>