2012-11-24 3 views
1

В принципе, это логика, которую я пытаюсь.Значение дочернего узла XSL-преобразования по-разному

Для родительских узлов (ByFirstNameSearchList или ByLastNameSearchList):

значения элементов -Вса Детей являются пустыми (value1-4), вставить значение% -Когда один или любые из дочернего элемента имеет значение, замените все братья и сестры с пустым значением с NOVAL.

У меня есть следующий XML:

<GetName> 
    <ByLastNameSearchList> 
     <Value1/> 
     <Value2/> 
     <Value3/> 
     <Value4/> 
     <Value5/> 
    </ByLastNameSearchList> 
    <ByFirstNameSearchList> 
     <Value1>String</Value1> 
     <Value2>String</Value2> 
     <Value3/> 
     <Value4/> 
     <Value5/> 
    </ByFirstNameSearchList> 
    </GetName> 

Это то, что я хочу, чтобы это выглядело как:

<GetName> 
    <ByLastNameSearchList> 
     <Value1>%</Value1> 
     <Value2>%</Value2> 
     <Value3>%</Value3> 
     <Value4>%</Value4> 
     <Value5>%</Value5> 
    </ByLastNameSearchList> 
    <ByFirstNameSearchList> 
     <Value1>String</Value1> 
     <Value2>String</Value2> 
     <Value3>NOVAL</Value3> 
     <Value4>NOVAL</Value4> 
     <Value5>NOVAL</Value5> 
    </ByFirstNameSearchList> 
</GetName> 

Я действительно ценю Вас помочь мне. Поверьте мне, я пробовал все с ограниченными знаниями XSL.

Спасибо.

ответ

0

Эта таблица стилей

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

    <xsl:template match="*|@*"> 
     <xsl:copy> 
     <xsl:apply-templates/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="ByFirstNameSearchList/* | ByLastNameSearchList/*"> 
     <xsl:copy> 
     <xsl:choose> 
      <xsl:when test="string-length(text()) gt 0"> 
       <xsl:value-of select="text()"/> 
      </xsl:when> 
      <xsl:when test="some $Value in ../* satisfies string-length($Value/text()) gt 0"> 
       <xsl:text>NOVAL</xsl:text> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:text>%</xsl:text> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

будет производить вывод, который вы хотите.

UPDATE:

Эта версия несколько более общий характер, так как она не опирается на непустых элементов, содержащих только строку:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

    <xsl:template match="*|@*"> 
     <xsl:copy> 
     <xsl:apply-templates/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="ByFirstNameSearchList/* | ByLastNameSearchList/*"> 
     <xsl:choose> 
     <xsl:when test="string-length(text()) gt 0"> 
      <xsl:copy-of select="."/> 
     </xsl:when> 
     <xsl:when test="some $Value in ../* satisfies string-length($Value/text()) gt 0"> 
      <xsl:copy> 
       <xsl:text>NOVAL</xsl:text> 
      </xsl:copy> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:copy> 
       <xsl:text>%</xsl:text> 
      </xsl:copy> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 
0

Как просто, как это (как для XSLT 2.0 и XSLT 1.0):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/*/*/*[not(node())]"> 
    <xsl:copy>NOVAL</xsl:copy> 
</xsl:template> 

<xsl:template match="/*/*[not(*/node())]/*"> 
    <xsl:copy>%</xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

Когда это преобразование применяется на прилагаемом документе XML:

<GetName> 
    <ByLastNameSearchList> 
     <Value1/> 
     <Value2/> 
     <Value3/> 
     <Value4/> 
     <Value5/> 
    </ByLastNameSearchList> 
    <ByFirstNameSearchList> 
     <Value1>String</Value1> 
     <Value2>String</Value2> 
     <Value3/> 
     <Value4/> 
     <Value5/> 
    </ByFirstNameSearchList> 
</GetName> 

разыскиваемый, правильный результат получается:

<GetName> 
     <ByLastNameSearchList> 
      <Value1>%</Value1> 
      <Value2>%</Value2> 
      <Value3>%</Value3> 
      <Value4>%</Value4> 
      <Value5>%</Value5> 
     </ByLastNameSearchList> 
     <ByFirstNameSearchList> 
      <Value1>String</Value1> 
      <Value2>String</Value2> 
      <Value3>NOVAL</Value3> 
      <Value4>NOVAL</Value4> 
      <Value5>NOVAL</Value5> 
     </ByFirstNameSearchList> 
</GetName> 

Объяснение:

  1. Удостоверения копии правил "как есть" каждый узел, для которого она выбран для выполнения.

  2. Шаблон переопределяет шаблон идентичности для любого элемента, который является грандиозным элементом верхнего элемента и у которого нет детей. Это копирует элемент и генерирует дочерний элемент текстового узла со строковым значением строку «NOVAL».

  3. Второй шаблон переопределения, который переопределяет как шаблон идентификации, так и первый шаблон переопределения: соответствует любому элементу, который является грандиозным элементом верхнего элемента и родительский элемент которого не имеет дочернего элемента с дочерним узлом. Это копирует элемент и генерирует дочерний элемент текстового узла со строковым значением строку «%».

ли Примечание:

  1. Это чистый "толчок стиль" трансформация.

  2. Там нет явных условных инструкций (нет xsl:choose, нет xsl:when, нет xsl:otherwise), не xsl:text и даже не xsl:apply-templates (за исключением шаблона идентичности).

  3. Нет специальных выражений XPath 2.0 (some ... satisfies ...), поскольку они не нужны.

  4. No string-length() функция используется.

+0

Спасибо Это работало как шарм. Только один вопрос. Каков порядок исполнения. Например, 3-й шаблон (), выполняется после 2-го преобразования на втором или работает самостоятельно самостоятельно копировать? – rafter

Смежные вопросы