xslt help - удалить пустые теги и заменить * пустыми тегами - PullRequest
1 голос
/ 21 июня 2010

У меня проблема при выполнении предварительной обработки XSLT в моей Java-программе.Мы получаем звездочку (*) из программы мэйнфрейма, когда она хочет очистить значение, которое мой Java-процесс должен обрабатывать как пустой или пустой тег.Таким образом, мы применяем xslt ко входу перед моим процессом jaxb.

Мы применяем этот 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/>

Пожалуйста, помогите.Любая помощь приветствуется, так как у меня не было этого теста во время тестирования моего кода.

Ответы [ 2 ]

1 голос
/ 21 июня 2010

Заменить :

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

на

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

Это гораздо более эффективно чем нужно вычислять строковое значение каждого элемента, потому что строковое значение элемента - это объединение всех его дочерних текстовых узлов.

1 голос
/ 21 июня 2010

Это потому, что . является внутренним текстом, который является объединением всех внутренних текстовых узлов.Вы должны убедиться, что в вашем состоянии нет дочернего узла или только текстового узла с * в качестве содержимого.

Это должно работать:

<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>
...