2014-12-19 91 views
3

我有XML文件:XSLT如何检查XML节点是否存在?

<?xml version="1.0" encoding="utf-8"?> 
<?xml-stylesheet type="text/xsl" href="test.xsl"?> 
<Data> 
    <Records> 
    <Record> 
    <AddInfo> 
     <Info> 
     </Info> 
    </AddInfo> 
    </Record> 
    </Records> 
</Data> 

和XSL文件:

<?xml version="1.0" encoding="iso-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="Dane"> 
    <html> 
     <link rel="stylesheet" type="text/css" href="report.css"></link> 
     <body> 
     <h2>Table1</h2> 
     <table border="1" cellspacing="0"> 
      <tr> 
      <th>XXX</th> 
      </tr> 
      <xsl:for-each select="Records/Record"> 
      <tr> 
       <td> 
       <xsl:value-of select="XXX"/> 
       </td> 
      </tr> 
      </xsl:for-each> 
     </table> 
     <h2>SecondTable</h2> 
     <table border="1" cellspacing="0"> 
      <tr> 
      <th>YYY</th> 
      <th>ZZZ</th> 
      </tr> 
      <xsl:for-each select="Records/Record/AddInfo/Info"> 
      <tr> 
       <td> 
       <xsl:value-of select="YYY"/> 
       </td> 
       <td> 
       <xsl:value-of select="ZZZ"/> 
       </td> 
      </tr> 
      </xsl:for-each> 
     </table> 
     </body> 
    </html> 
    </xsl:template> 
</xsl:stylesheet> 

我想让它这样的:如果节点存在,则与“信息”节点显示表,如果没有,显示一些文字。

我一直在试图

<xsl:if test="following-sibling::AddInfo"> 
</xsl:if> 

<xsl:if test="AddInfo"> 
</xsl:if> 

但它无法正常工作。

我希望它是这样的:

Table1 
--------------------- 
|  |  |  | 

(条件:如果内部的XML将是节点,我想显示第二个表,表1下)

SecondTable 
------------- 
|  |  | 

我怎样才能做到这一点?

+1

目前还不清楚是什么你在问。一件重要的事情,你没有公布你的预期产出。并且,将所有场景放入您想要处理的输入XML中。 – 2014-12-19 11:18:03

+1

你的问题不清楚。你想在哪里插入这个测试?你只有一个普通表,所以“*如果节点存在,显示带有”Info“节点的表,如果不存在,则显示”SOME TEXT *“几乎没有意义。 – 2014-12-19 11:19:34

+0

所以,你说如果addInfo元素不存在,应该显示一些文本? – Rnet 2014-12-19 11:24:02

回答

11

此输出Yep如果<AddInfo>存在的<Record>立竿见影的孩子,否则Nope

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="Data"> 
    <xsl:for-each select="Records/Record"> 
     <xsl:choose> 
     <xsl:when test="AddInfo">Yep</xsl:when> 
     <xsl:otherwise>Nope</xsl:otherwise> 
     </xsl:choose> 
    </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

注意,你不需要for-each,你应该让第二个模板匹配每个<Record>

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="Data/Records/Record"> 
    <xsl:choose> 
     <xsl:when test="AddInfo">Yep</xsl:when> 
     <xsl:otherwise>Nope</xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

您也可以避免choose并使用两个独立的if条件:

<xsl:template match="Data/Records/Record"> 
    <xsl:if test="AddInfo">Yep</xsl:if> 
    <xsl:if test="not(AddInfo)">Nope</xsl:if> 
    </xsl:template> 

如果您不想将其限制为直接子女,请改为使用.//AddInfo

考虑以下样式:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="Data"> 
    <xsl:apply-templates select="Records/Record"/> 
    </xsl:template> 

    <xsl:template match="Data/Records/Record"> 
    <table class="one"></table> 
    <xsl:if test="AddInfo"> 
     <table class="two"></table> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

它输出

<table class="one"></table> 

,如果有在<Record>没有<AddInfo>节点,

<table class="one"></table> 
<table class="two"></table> 

否则。

您既可以使用if也可以使用choose来解决这个问题。XML:

<?xml version="1.0" encoding="utf-8"?> 
<?xml-stylesheet type="text/xsl" href="test.xsl"?> 
<Data> 
    <AddInfo> 
    <Info>This is ignored</Info> 
    </AddInfo> 
    <Records> 
    <Record> 
     <AddInfo> 
      <Info>One,</Info> 
      <Info>Two,</Info> 
      <Info>Three</Info> 
     </AddInfo> 
    </Record> 
    <Record> 
     <Info>Ignored as well</Info> 
    </Record> 
    <Record> 
     <Nested> 
     <AddInfo> 
      <Info>So is this</Info> 
     </AddInfo> 
     </Nested> 
    </Record> 
    </Records> 
</Data> 

XSLT:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="Data"> 
    <root> 
     <xsl:apply-templates select="Records/Record"/> 
    </root> 
    </xsl:template> 

    <xsl:template match="Data/Records/Record"> 
    <xsl:copy> 
     <table id="one"></table> 
     <xsl:apply-templates select="AddInfo"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Data/Records/Record/AddInfo"> 
    <table id="two"> 
     <xsl:apply-templates select="Info"/> 
    </table> 
    </xsl:template> 

    <xsl:template match="Data/Records/Record/AddInfo/Info"> 
    <xsl:value-of select="."/> 
    </xsl:template> 

</xsl:stylesheet> 

输出:

<root> 
    <Record> 
    <table id="one" /> 
    <table id="two">One,Two,Three</table> 
    </Record> 
    <Record> 
    <table id="one" /> 
    </Record> 
    <Record> 
    <table id="one" /> 
    </Record> 
</root> 
+0

看起来像我已经测试过这样的东西,它是不工作,因为如果在我生成的XML中没有“AddInfo”节点,SecondTable(YYY,ZZZ)的标题仍然显示,而不是此标题,我想显示SOME TEXT。 – vBB 2014-12-19 11:42:01

+0

条件节点当然需要包装生成第二个表的所有节点。看到我更新的答案。 – CoDEmanX 2014-12-19 11:54:26

+0

谢谢!现在它正在工作:) – vBB 2014-12-19 12:33:55

0

要检查是否节点XML存在这个XSLT代码工作

<xsl:choose> 
       <xsl:when test="XMLNodeName"> 
        <Cell ss:Index="2" ss:StyleID="s110"> 
        <Data ss:Type="String"> 
         <xsl:value-of select="NodeOne"/> 
        </Data> 
        </Cell> 
       </xsl:when> 
       <xsl:otherwise> 
        <Cell`enter code here` ss:Index="2" ss:StyleID="s110"> 
        <Data ss:Type="String"> 
         <xsl:value-of select="NodeTwo"/> 
        </Data> 
        </Cell> 
       </xsl:otherwise> 
</xsl:choose> 
相关问题