1

在我的 java 程序中进行一些 XSLT 预处理时遇到问题。当大型机程序想要清除一个值时,我们会从它那里得到一个星号 (*),我的 java 进程必须将其视为空白或空标记。因此,我们在我的 jaxb 进程之前将 xslt 应用于输入。

我们正在应用这个 xslt :

  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="no"/>
  <xsl:template match="@*[. = '*']">
    <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
      <xsl:text></xsl:text>
    </xsl:attribute>
  </xsl:template>
  <xsl:template match="*[. = '*']">
    <xsl:copy>
      <xsl:text></xsl:text>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

上面的 xslt 几乎适用于所有测试用例。除非只有一个子元素并且恰好是一个星号。

例如在输入中考虑这个:

<MYROOT><Address3><Line2>*</Line2><Line3>*</Line3></Address3></MYROOT>

效果很好。它产生这个输出:

<MYROOT><Address3><Line2/><Line3/></Address3></MYROOT>

但是,下面的 xml 输入会产生不正确的响应。

<MYROOT><Address4><PermanentAddress><Line2>*</Line2></PermanentAddress></Address4></MYROOT>

但是,而不是给出响应

<MYROOT><Address4><PermanentAddress><Line2></Line2></PermanentAddress></Address4></MYROOT>

它给出了这个:

<MYROOT/>

请帮忙。感谢任何帮助,因为我在测试我的代码时没有这个测试用例。

4

2 回答 2

1

那是因为.是内部文本,它是所有内部文本节点的串联。您需要确保在您的条件下没有子节点或只有带有 * 作为内容的文本节点。

这应该有效:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="no"/>

    <xsl:strip-space elements="*"/>

    <xsl:template match="*[not(*) and (. = '*')] | @*[. = '*']">
        <xsl:copy />
    </xsl:template>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
于 2010-06-21T19:34:41.783 回答
1

替换

<xsl:template match="*[. = '*']"> 
    <xsl:copy> 
      <xsl:text></xsl:text> 
    </xsl:copy> 
  </xsl:template>

  <xsl:template match="*[not(*) and not(text()[2])]/text()[.='*']"/>

这比必须计算每个元素的字符串值要高效得多,因为一个元素的字符串值是其所有后代文本节点的串联。

于 2010-06-21T19:43:10.310 回答