避免在缺少“匹配”实体的情况下输出属性

时间:2019-12-01 02:49:02

标签: xml xslt

执行XSLT后,我有一张类似的图片(某些属性值为空)

  <Document
            Region="Earth"
            City="Tokio"
            District=""
            Street="" >
  </Document>

我的XSLT是

<xsl:template match="Document">
     <Document
            Region="{Region/@attr1}" 
            City="{City/@attr2}"  
            District="{District/@attr3}"  
            Street="{Street/@attr4}"  >
      <xsl:apply-templates />
    </Document>
  </xsl:template>

所有Xpathes都是正确的。事实是,正如我想的那样,我的代码太“直接”了。需要更多的灵活性。简要地说,符合条件:“如果没有值\属性可捕获源XML,则输出节点中不应有任何相应的记录”。在示例代码{District / @ attr3}和{Street / @ attr4}中,Xpath \ Expression可能返回一些值,但有时不返回(这样,源节点中甚至没有属性)。因此,在{District / @ attr3}和{Street / @ attr4}返回\“匹配”的情况下,所需的输出看起来像没有什么

所需的输出

  <Document 
            Region="Earth"
            City="Tokio" >
  </Document>

如何改进XSLT代码(1.0)?

2 个答案:

答案 0 :(得分:1)

以前的答案很好,但是对于不太熟悉XSLT的人来说很难理解。 我只会添加if语句来测试源文档中是否存在该节点。

<xsl:template match="Document">
  <xsl:element name="Document"/>
    <xsl:attribute name="Region" select="Region/@attr1"/>
    <xsl:attribute name="City" select="City/@attr2"/>
    <xsl:if test="District/@attr3">
      <xsl:attribute name="District" select="District/@attr3"/>
    </xsl:if>
    <xsl:if test="Street/@attr4">
      <xsl:attribute name="Street" select="Street/@attr4"/>
    </xsl:if>
      <xsl:apply-templates />
  </xsl:element>
</xsl:template>

您也可以替换

<xsl:element name="Document"/> with <xsl:copy>

答案 1 :(得分:0)

很难看到更广阔的前景。尝试类似的东西:

<xsl:template match="Document">
    <Document
            Region="{Region/@attr1}" 
            City="{City/@attr2}" >
        <xsl:apply-templates select="District/@attr3 | Street/@attr4"/>
        <xsl:apply-templates/>
    </Document>
</xsl:template>

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

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

或者也许:

<xsl:template match="Document">
    <Document
            Region="{Region/@attr1}" 
            City="{City/@attr2}" >
        <xsl:apply-templates select="District/@attr3 | Street/@attr4"/>
        <xsl:apply-templates/>
    </Document>
</xsl:template>

<xsl:template match="District/@attr3 | Street/@attr4">
    <xsl:attribute name="{name(..)}">
        <xsl:value-of select="."/>
    </xsl:attribute>
</xsl:template>

未经测试,因为未提供测试输入。


请注意,这假设属性将具有值或根本不存在-并非它们为空。如果它们可以为空,则需要添加一个谓词,例如:

<xsl:apply-templates select="(District/@attr3 | Street/@attr4)[string()]"/>