Xml 访问模板中的节点,该模板从中为每个

Xml 访问模板中的节点,该模板从中为每个,xml,xslt,Xml,Xslt,我是XSLT的新手,所以我确信这非常简单,但我无法理解。我试图将输出为简单xml的报告转换为管道分隔的文件。我不知道如何从模板内部访问wd:SSN,该模板是从for-each中调用的。报告的xml输出如下所示 <wd:Report_Data xmlns:wd="urn:com.workday.report/Report_ABC"> <wd:Report_Entry> <wd:Company> <wd:Company_Code>

我是XSLT的新手,所以我确信这非常简单,但我无法理解。我试图将输出为简单xml的报告转换为管道分隔的文件。我不知道如何从模板内部访问wd:SSN,该模板是从for-each中调用的。报告的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>
谢谢你的帮助

在for-each选择中,您得到了[wd:Company/wd:Company\u 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),然后从那里重新构建。

您将名称空间绑定到一个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>
<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>
到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>
<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>

很抱歉,我忘了将wd:company节点放在xml中,我将其更新为包含该节点。我遇到的问题是访问wd:SSN。当我把它直接放在for-each中时,它工作得很好。但是,由于处理一个员工的代码部分实际上是600多行,我需要为多个公司执行这部分代码,所以我将其拆分为ProcessCompanyEmployee模板。当我这样做的时候,它不再像wd:SSN了。我假设我需要以不同的方式引用wd:SSN等字段,但我不知道这是什么。这能更好地解释我的问题吗?啊…我读得更多了。听起来我可能需要ProcessCompanyEmployee模板中的匹配模式来提供上下文,但我不知道应该是什么。我尝试了wd:Report\u条目,我尝试了wd:Report\u Data/wd:Report\u条目,但两者都不起作用。您期望的输出是什么?我替换了在&xa;的样式表中没有定义的insertNewLine模板;换行和移动的xmlns:wd。。。到根标记,并且管道分隔的输出没有出现错误。不清楚您的问题是什么。我的xslt代码有5000多行。我只包括与我的问题相关的代码部分。我的问题是在ProcessCompanyEmployee模板中引用wd:SSN失败。您是否将xmlns:wd=urn:com.workday.report/report\u ABC放在xslt的根标记中?抱歉,我忘记将wd:company节点放在xml中,我已将其更新为包含该节点。我遇到的问题是访问wd:SSN。当我把它直接放在for-each中时,它工作得很好。但是,由于处理一个员工的代码部分实际上是600多行,我需要为多个公司执行这部分代码,所以我将其拆分为ProcessCompanyEmployee模板。当我这样做的时候,它不再像wd:SSN了。我假设我需要以不同的方式引用wd:SSN等字段,但我不知道这是什么。这能更好地解释我的问题吗?我是通过将xmlns:wd=urn:com.workday.report/report_ABC放在xsl:stylesheet元素上,或者放在两个模板声明上实现的。丹尼尔·海利的答案是我所说的最正确的答案。谢谢杰夫!你和丹尼尔·海利的想法都解决了我的问题。Daniel跑得更快,正如你所说,可能更好,因为它最终只在代码中的一个位置。完美!谢谢你,丹尼尔!这解决了我的问题!谢谢你!我知道的不足以理解你的上一句话,但我的代码正在运行,所以我想我现在还可以。@RDay-不客气!我还添加了一个示例来说明我在上一次发言中所说的内容。基本上,我从xpath中去掉了所有的wd:前缀,并将xsl:stylesheet上的xmlns:wd更改为xpath默认名称空间。它使XPath在更大的样式表中更加清晰,其中大多数XPath指向同一名称空间中的元素/属性。