1

基本上,这是我正在尝试的逻辑。

对于父节点(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 知识尝试了一切。

谢谢。

4

2 回答 2

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>

将产生你想要的输出。

更新:

这个版本更通用一些,因为它不依赖于只包含一个字符串的非空元素:

<?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>
于 2012-11-24T21:05:08.247 回答
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. 没有明确的条件指令(no xsl:choose, no xsl:when, no xsl:otherwise),noxsl:text甚至 no xsl:apply-templates(身份模板除外)。

  3. 没有some ... satisfies ...使用特殊的 XPath 2.0 表达式 ( ),因为它们是不必要的。

  4. 没有string-length()使用任何功能。

于 2012-11-24T21:28:10.037 回答