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

Xml 避免在缺少“的情况下输出属性”;“匹配”;实体,xml,xslt,Xml,Xslt,在XSLT执行之后,我看到了一幅图(一些属性的值为空) 我的XSLT是 <xsl:template match="Document"> <Document Region="{Region/@attr1}" City="{City/@attr2}" District="{District/@attr3}" Street="{Street/@attr4}" &g

在XSLT执行之后,我看到了一幅图(一些属性的值为空)


我的XSLT是

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

所有的XPath都是正确的。问题是,正如我所想,我的代码太“直接”。需要更多的灵活性。简单地说,符合条件:“如果源XML中没有要捕获的value\attribute,那么输出节点中不应该有任何相应的记录”。在示例代码{District/@attr3}和{Street/@attr4}中,Xpath\Expression可能返回一些值,但有时不返回(源节点中甚至没有属性)。因此,当{District/@attr3}和{Street/@attr4}返回\“matching”时,所需的输出必须如下所示:

所需输出

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


如何改进XSLT代码(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()]"/>

前面的答案很好,但对于不太熟悉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>
请始终发布一条信息,包括输入信息。
<xsl:element name="Document"/> with <xsl:copy>