访问从for-each中调用的模板中的节点

时间:2017-12-15 01:50:19

标签: xml xslt

我是XSLT的新手,所以我确信这很简单,但我无法得到它。我正在尝试将输出的报告转换为简单的xml到管道分隔文件中。我无法弄清楚如何从一个for-each中调用的模板内部访问wd:SSN。报告中的xml输出看起来像这样。

<wd:Report_Data xmlns:wd="urn:com.workday.report/Report_ABC">
  <wd:Report_Entry>
    <wd:Company>
      <wd:Company_Code>123</wd:Company_Code>
    </wd:Company>
    <wd:Employee_Last_Name>Smith</wd:Employee_Last_Name>
    <wd:Employee_First_Name>Joe</wd:Employee_First_Name>
    <wd:SSN>123456789</wd:SSN>
    <wd:Street_Address>123 First St</wd:Street_Address>
    <wd:City>Colorado Springs</wd:City>
    <wd:State_Province>CO</wd:State_Province>   
    <wd:ZIP_Code>80927</wd:ZIP_Code>
  </wd:Report_Entry>
  <wd:Report_Entry>
    <wd:Company>
      <wd:Company_Code>123</wd:Company_Code>
    </wd:Company>
    <wd:Employee_Last_Name>Smith</wd:Employee_Last_Name>
    <wd:Employee_First_Name>Sally</wd:Employee_First_Name>
    <wd:SSN>123456790</wd:SSN>
    <wd:Street_Address>123 First St</wd:Street_Address>
    <wd:City>Colorado Springs</wd:City>
    <wd:State_Province>CO</wd:State_Province>
    <wd:ZIP_Code>80927</wd:ZIP_Code>
  </wd:Report_Entry>

然后我的代码看起来像这样

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:strip-space elements="*"/>
<xsl:output method="text" indent="no"/>
<xsl:template match="wd:Report_Data" xmlns:wd="urn:com.workday.report/Report_ABC">

  <!-- Loop thru employee records for Company 123 -->
  <xsl:for-each select="wd:Report_Entry[wd:Company/wd:Company_Code = '123']">
    <xsl:call-template name="ProcessCompanyEmployee"/>      
  </xsl:for-each>
</xsl:template>

<!-- Process Company Employee -->
<xsl:template name="ProcessCompanyEmployee">
<!-- EMP Employee Record -->
  <xsl:text>EMP|N|N</xsl:text>
  <xsl:text>|</xsl:text>
  <xsl:text>|</xsl:text>
  <xsl:value-of select="wd:SSN"/>
  <xsl:text>||</xsl:text>
  <xsl:call-template name="insertNewLine"/>
</xsl:template>

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

您在一个xsl:template上绑定命名空间,但也尝试在另一个xsl:template中使用它。

尝试将xmlns:wd声明移至xsl:stylesheet。

示例...

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:wd="urn:com.workday.report/Report_ABC">
  <xsl:strip-space elements="*"/>
  <xsl:output method="text" indent="no"/>

  <xsl:template match="wd:Report_Data">
    <!-- Loop thru employee records for Company 123 -->
    <xsl:for-each select="wd:Report_Entry[wd:Company/wd:Company_Code = '123']">
      <xsl:call-template name="ProcessCompanyEmployee"/>      
    </xsl:for-each>
  </xsl:template>

  <!-- Process Company Employee -->
  <xsl:template name="ProcessCompanyEmployee">
    <!-- EMP Employee Record -->
    <xsl:text>EMP|N|N</xsl:text>
    <xsl:text>|</xsl:text>
    <xsl:text>|</xsl:text>
    <xsl:value-of select="wd:SSN"/>
    <xsl:text>||</xsl:text>
    <xsl:call-template name="insertNewLine"/>
  </xsl:template>

  <xsl:template name="insertNewLine">
    <xsl:text>&#xA;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

此外,由于您使用的是XSLT 2.0,因此您无法在XPath中使用前缀并添加:

xpath-default-namespace="urn:com.workday.report/Report_ABC"

到xsl:stylesheet。

示例...

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xpath-default-namespace="urn:com.workday.report/Report_ABC">
  <xsl:strip-space elements="*"/>
  <xsl:output method="text" indent="no"/>

  <xsl:template match="Report_Data">
    <!-- Loop thru employee records for Company 123 -->
    <xsl:for-each select="Report_Entry[Company/Company_Code = '123']">
      <xsl:call-template name="ProcessCompanyEmployee"/>      
    </xsl:for-each>
  </xsl:template>

  <!-- Process Company Employee -->
  <xsl:template name="ProcessCompanyEmployee">
    <!-- EMP Employee Record -->
    <xsl:text>EMP|N|N</xsl:text>
    <xsl:text>|</xsl:text>
    <xsl:text>|</xsl:text>
    <xsl:value-of select="SSN"/>
    <xsl:text>||</xsl:text>
    <xsl:call-template name="insertNewLine"/>
  </xsl:template>

  <xsl:template name="insertNewLine">
    <xsl:text>&#xA;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

在您的for-each select中,您有[wd:Company/wd:Company_Code = '123'],但XML不包含wd:Company元素。

以下模板用于转换XML:

<xsl:template match="/">
    <xsl:for-each select="//wd:Report_Entry[wd:Company_Code = '123']">
        <xsl:text>EMP|N|N</xsl:text>
        ...
        <xsl:value-of select="wd:SSN"/>
        ...
    </xsl:for-each>
</xsl:template>

使用原始匹配/选择如下:

<xsl:template match="wd:Report_Data">
    <xsl:for-each select="wd:Report_Entry[wd:Company_Code = '123']">

在测试XSLT时,它有助于减少模板的使用并使其运行以选择一个元素(比如SSN),然后从那里进行备份。