0

我从数据库 xml 字符串中检索:

任何一个 :

<?xml version="1.0" ?>
<Parameters>
  <StringParameter name="field">TNA</StringParameter>
  <DateParameter name="date">2011-12-14T00:00:00</DateParameter>
</Parameters>

任何一个 :

<?xml version="1.0" ?>
<ArrayOfPrimitiveParameter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <PrimitiveParameter>
    <Name>field</Name>
    <Value xsi:type="xsd:string">TNA</Value>
  </PrimitiveParameter>
  <PrimitiveParameter>
    <Name>date</Name>
    <Value xsi:type="xsd:dateTime">2011-12-14T00:00:00</Value>
  </PrimitiveParameter>
</ArrayOfPrimitiveParameter>

我只想在第二种情况下转换输出。但是我的 xslt 样式表转换了所有情况(1 和 2)。今天我已经使用 SQL Where 过滤器解决了问题,但我想知道如何使用 XSL 来做到这一点。

这是我的 XsltStyleSheet :

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xsd xsi" 
>
  <xsl:output method="xml" omit-xml-declaration="yes" standalone="yes"  />
  <xsl:template match="ArrayOfPrimitiveParameter" >

    <Parameters>
      <xsl:apply-templates />
    </Parameters>
  </xsl:template>

  <xsl:template match="PrimitiveParameter">

    <!-- String -->
    <xsl:if test="Value/@xsi:type='xsd:string'">
     <xsl:element name="StringParameter">
       <xsl:attribute name="name">
          <xsl:value-of select="Name" />
        </xsl:attribute>

        <xsl:if test="Key">
          <xsl:attribute name="DomainKey">
            <xsl:value-of select="Key" />
          </xsl:attribute>
        </xsl:if>
        <xsl:value-of select="Value" />
      </xsl:element>
    </xsl:if>

    <!-- DateTime -->
    <xsl:if test="Value/@xsi:type='xsd:dateTime'">
      <xsl:element name="DateParameter">
        <xsl:attribute name="name">
          <xsl:value-of select="Name" />
        </xsl:attribute>
        <xsl:value-of select="Value" />
      </xsl:element>
    </xsl:if>

    <!-- Boolean -->
    <xsl:if test="Value/@xsi:type='xsd:boolean'">
      <xsl:element name="BoolParameter">
        <xsl:attribute name="name">
          <xsl:value-of select="Name" />
        </xsl:attribute>
        <xsl:value-of select="Value" />
      </xsl:element>
    </xsl:if>

    <!-- Double -->
    <xsl:if test="Value/@xsi:type='xsd:double'">
      <xsl:element name="BoolParameter">
        <xsl:attribute name="name">
          <xsl:value-of select="Name" />
        </xsl:attribute>
        <xsl:value-of select="Value" />
      </xsl:element>
    </xsl:if>

  </xsl:template>
</xsl:stylesheet>

问候,

弗洛里安

4

2 回答 2

2

我建议将您的样式表基于身份模板。这将输出所有输入不变 - 除了您明确为其编写模板的元素。

<xsl:stylesheet 
  version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xsd xsi" 
>
  <xsl:output method="xml" omit-xml-declaration="yes" standalone="yes"  />

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

  <xsl:template match="ArrayOfPrimitiveParameter">
    <Parameters>
      <xsl:apply-templates />
    </Parameters>
  </xsl:template>

  <xsl:template match="PrimitiveParameter">
    <xsl:variable name="elemName">
      <xsl:apply-templates select="Value/@xsi:type" />
    </xsl:variable>

    <xsl:element name="{$elemName}">
      <xsl:apply-templates select="Name | Key" />
      <xsl:value-of select="Value" />
    </xsl:element>
  </xsl:template>

  <xsl:template match="@xsi:type">
    <xsl:choose>
      <xsl:when test=". = 'xsd:string'">StringParameter</xsl:when>
      <xsl:when test=". = 'xsd:dateTime'">DateParameter</xsl:when>
      <xsl:when test=". = 'xsd:boolean'">BoolParameter</xsl:when>
      <xsl:when test=". = 'xsd:double'">DoubleParameter</xsl:when>
      <xsl:otherwise>UnknownParameter</xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="Name">
    <xsl:attribute name="name">
      <xsl:value-of select="." />
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="Key">
    <xsl:attribute name="DomainKey">
      <xsl:value-of select="." />
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

请注意,我重写了您的方法,使其更通用。看看你喜不喜欢这个变化。

于 2013-10-10T12:08:34.007 回答
1

您可以通过匹配并且不对其执行任何操作来显式忽略输入文档中的元素:

  <xsl:template match="Parameters"/>

这将匹配和抑制Parameters,覆盖任何更一般的匹配,例如默认情况下用于将元素复制到输出。

请注意,它不会覆盖更具体的匹配模式:

  <xsl:template match="Parameters[StringParameter/@name = 'field']">
  ...
  </xsl:template>
于 2013-10-10T11:59:24.960 回答