2012-11-24 49 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. string-length()功能被使用。

+0

谢谢这就像一个魅力。只是一个问题。执行的顺序是什么?例如,第三个模板()在第二次转换后执行,还是独立工作复制? – rafter