我有一个大的xml文件,其中包含许多自闭标签。如何使用XSLT删除它们。
例如。
<?xml version="1.0" encoding="utf-8" ?>
<Persons>
<Person>
<Name>user1</Name>
<Tel />
<Mobile>123</Mobile>
</Person>
<Person>
<Name>user2</Name>
<Tel>456</Tel>
<Mobile />
</Person>
<Person>
<Name />
<Tel>123</Tel>
<Mobile />
</Person>
<Person>
<Name>user4</Name>
<Tel />
<Mobile />
</Person>
</Persons>
我期待结果:
<?xml version="1.0" encoding="utf-8" ?>
<Persons>
<Person>
<Name>user1</Name>
<Mobile>123</Mobile>
</Person>
<Person>
<Name>user2</Name>
<Tel>456</Tel>
</Person>
<Person>
<Tel>123</Tel>
</Person>
<Person>
<Name>user4</Name>
</Person>
</Persons>
注意:有数千个不同的元素,如何以编程方式删除所有自闭标签。另一个问题是如何删除<name></name>
之类的空元素。
任何人都可以帮我这个吗?非常感谢。
答案 0 :(得分:9)
自闭标签相当于空标签。您可以删除所有空标记,但无法知道它们是否在输入XML中自行关闭(<tag/>
和<tag></tag>
无法区分)。
<!-- the identity template copies everything that has no special handler -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<!-- special handler for elements that have no child nodes:
they are removed by this empty template -->
<xsl:template match="*[not(node())]" />
如果您的定义中仅包含空格的元素也为“空”,则将第二个模板替换为:
<xsl:template match="*[normalize-space() = '']" />
答案 1 :(得分:1)
从XML的角度来看,“自闭”元素和空元素之间没有区别(见spec)。
这是一个去除所有空元素的转换:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="utf-8" />
<xsl:strip-space elements="*" />
<xsl:template match="@*|node()">
<xsl:if test=".!=''">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:0)
您可能想要检查是否需要它们。如果它们是:use =“required”,它应该看起来像这样。还要检查它们是否:type =“non Empty String”。
答案 3 :(得分:0)
您可以删除所有空元素 - 没有声明嵌套元素和属性的元素。如果此解决方案适合您,您可以执行以下操作:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<xsl:if test="string(.) != '' or descendant-or-self::*/@*[string(.)]">
<xsl:element name="{name()}" >
<xsl:copy-of select="@*[string(.)]"/>
<xsl:apply-templates select="* | text()" />
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
答案 4 :(得分:0)
发布此答案的原因是, 你还没有接受任何一个 现有答案。
好。这是非常简单的XSLT挑战。只需将带有文本数据的节点与null匹配并关闭模板标记,这样,节点就不会出现在输出中。
像这样,<xsl:template match=*[.='']/>
将它与您的身份模板一起添加。与Tomolak钉牢的方式类似。
这种方法的问题是,如果它为null,它甚至会删除你的父节点(例如<Person/>
标记)。
如果这是你的xml:
<Persons>
<Person>
<data>text</data>
<data2>text</data2>
<data3/>
</Person>
<Person/>
</Persons>
从上面的xml中删除了标签。所以输出xml将是:
<Persons>
<Person>
<data>text</data>
<data2>text</data2>
</Person>
</Persons>
如果您想避免这种情况,请添加例外。
<xsl:template match="*[name()!='Person' and not(node())]"/>
添加您的身份模板。你的XSLT将是:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[name()!='Person' and not(node())]"/>
</xsl:stylesheet>
输出xml将是:
<Persons>
<Person>
<data>text</data>
<data2>text</data2>
</Person>
<Person/>
</Persons>