当<value-of select =“”>为空时</value-of>阻止xsl表生成新元素

时间:2014-09-11 13:06:05

标签: xml xslt

我必须重新创建一个新的xml,其中包含来自&#39; old&#39;的标签名称和值。 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中输入不同名称标签的值。希望这会对此有所了解,我仍然在努力解决这个问题并且不确定如何解决这个问题。

3 个答案:

答案 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>