[英]Call Template with Parameter and Output Value - XSLT
I have an 1 large xml file composed of 2 different xml files. 我有一个由2个不同的xml文件组成的1个大xml文件。 What I want to do is, when I create a CSV file, I want to be able to grab data from the second part of the file that matches the first part.
我想要做的是,当我创建CSV文件时,我希望能够从与第一部分匹配的文件的第二部分中获取数据。 I use a for each loop to go through all of the data in the first portion of the file, and then a nested loop to grab matching data.
我为每个循环使用a来遍历文件第一部分中的所有数据,然后使用嵌套循环来获取匹配的数据。 Here is the XML layout:
这是XML布局:
<?xml version="1.0" encoding="UTF-8"?>
<Report_Data>
<Report_Entry>
<company_id>001</company_id>
<dept>TestDept</dept>
</Report_Entry>
<Report_Entry>
</Report_Entry>
<Company_Data>
<Report_Entry>
<code>1</code>
<name>Test1</name>
</Report_Entry>
<Report_Entry>
<code>2</code>
<name>Test2</name>
</Report_Entry>
</Company_Data>
</Report_Data>
What I would like in my CSV is to have the name from the Company_Data node inserted into the output right after the company_id. 我想在CSV文件中将Company_Data节点的名称插入到company_id之后的输出中。
Here is my XSL File (it currently does not work, it loops through and outputs N/A for each company data node in the output file): 这是我的XSL文件(当前不起作用,它循环并为输出文件中的每个公司数据节点输出N / A):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wd="urn:com.workday/bsvc">
<xsl:output method="text" encoding="utf-8" media-type="text/plain" />
<xsl:strip-space elements="*"/>
<xsl:variable name="newline" select="'
'" />
<xsl:variable name="tab" select="'	'" />
<xsl:variable name="comma" select="','" />
<xsl:variable name="padding" select="' '" />
<xsl:variable name="ID" select="concat('COMPANY ID', $padding)" />
<xsl:variable name="NAME" select="concat('COMPANY NAME', $padding)" />
<xsl:variable name="DEPT" select="concat('DEPARTMENT', $padding)" />
<xsl:template match="/">
<xsl:value-of select="$ID"/><xsl:value-of select="$comma"/>
<xsl:value-of select="$NAME"/><xsl:value-of select="$comma"/>
<xsl:value-of select="$DEPT"/><xsl:value-of select="$comma"/>
<xsl:for-each select="/Report_Data/Report_Entry">
<xsl:value-of select="translate(substring(concat(company_id, $padding), 1, string-length($ID)), ',', ' ')" /><xsl:value-of select="$comma"/>
<xsl:call-template name="company_name">
<xsl:with-param name="id_number" select="company_id"></xsl:with-param>
</xsl:call-template>
<xsl:value-of select="translate(substring(concat(dept, $padding), 1, string-length($DEPT)), ',', ' ')" /><xsl:value-of select="$comma"/>
</xsl:for-each>
</xsl:template>
<xsl:template name="company_name" match="/wd:Report_Data/wd:Company_Data">
<xsl:param name="id_number"></xsl:param>
<xsl:for-each select="/wd:Report_Entry">
<xsl:if test="contains($id_number, code)">
<xsl:value-of select="/name/text()"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
My output looks like this: 我的输出如下所示:
1, TestDept
Instead of: 代替:
1, Test1, TestDept
It is not outputting the value of the name
node. 它不输出
name
节点的值。 How can I get it to display the value? 我怎样才能显示它的价值?
I can add stuff if more info is needed. 如果需要更多信息,我可以添加东西。
I cannot add a comment to ask for clarification on what you are expecting to output exactly, but some observations: 我无法添加评论以要求澄清您期望准确输出的内容,但有一些观察结果:
Currently your stylesheet will go through each company_id element, and for each one it finds it will loop through every Company_Data/Report_Entry element. 当前,您的样式表将遍历每个company_id元素,并且找到的每个样式表将遍历每个Company_Data / Report_Entry元素。 You are seeing N/A because for each company_id it checks every single Company_Data/Report_Entry, and is outputting N/A for any that don't match the current company_id.
您会看到N / A,因为它会为每个company_id检查每个单独的Company_Data / Report_Entry,并为与当前company_id不匹配的任何内容输出N / A。 To me it looks like you just need to remove the otherwise (in which case you wouldn't need a choose, just an if).
在我看来,您只需要删除else(在这种情况下,您无需选择,只需一个if)。 Note that when I tried running your stylesheet I was getting 001,Test1,N/A,,Test1,N/A, so slightly different to yours (but I had to add a missing for-each closing tag).
请注意,当我尝试运行样式表时,得到的是001,Test1,N / A ,, Test1,N / A,与您的略有不同(但是我必须添加一个缺少的for-each结束标记)。
In terms of the code and name elements, because you are in the for loop the focus has shifted to the element being looped on (Report_Data/Company_Data/Report_Entry) so you can use relative paths which will navigate from that looped element. 就代码和名称元素而言,由于您处于for循环中,因此焦点已转移到要循环的元素(Report_Data / Company_Data / Report_Entry),因此您可以使用将从该循环的元素导航的相对路径。 So you can just use "code" or "name".
因此,您可以只使用“代码”或“名称”。 You don't even need the "./" as this produces the same result.
您甚至不需要“ ./”,因为这会产生相同的结果。
You don't need to use an inner xsl:for-each loop here to look up the company name. 您无需在此处使用内部xsl:for-each循环来查找公司名称。 You could just use an xsl:variable here with a select parameter where you can put your 'contains' expressions
您可以在此处仅使用xsl:variable和select参数,在其中可以放置“包含”表达式
<xsl:for-each select="Report_Data/Report_Entry">
<xsl:variable
name="company_name"
select="/Report_Data/Company_Data/Report_Entry[contains(current()/company_id, code)]/name" />
Note the use of current() here, which is to ensure the expression uses the company_id of the current Report_Data/Report_Entry element you are on, as opposed to the Company_Data/Report_Entry you are searching in the expression. 请注意此处使用current() ,以确保表达式使用您正在使用的当前Report_Data / Report_Entry元素的company_id ,而不是您在表达式中搜索的Company_Data / Report_Entry 。 If you were to do what you were currently doing, namely
/Report_Data/Report_Entry/company_id
, then this is an 'absolute' expression which starts from the top-level document node and will always return the first company_id in the XML. 如果要执行当前正在执行的操作,即
/Report_Data/Report_Entry/company_id
,那么这是一个“绝对”表达式,它从顶级文档节点开始,并且始终会返回XML中的第一个company_id 。
But in anycase, you could then simply output this variable, or use an xsl:choose to output 'NA' instead should the variable be empty (ie No company name was found). 但是无论如何,您都可以简单地输出该变量,或者使用xsl:choose输出'NA'来代替,如果变量为空(即未找到公司名称)。
Were it not for the fact the ids do not match up, such looking up of values are usually better handled with a key. 不是因为id不匹配,通常使用键可以更好地处理值的查找。 To look up an Report_Entry by its code you would define a key like so
要通过其代码查找Report_Entry,您需要定义一个键,如下所示
<xsl:key name="company" match="Company_Data/Report_Entry" use="code" />
Then to look it up you could do something like this... 然后要查找它,您可以执行以下操作...
<xsl:for-each select="Report_Data/Report_Entry">
<xsl:variable name="company_name" select="key('company', company_id)" />
Of course, this would fail in your case because the ids are not exactly the same, but perhaps you can just remove leading zeroes. 当然,在这种情况下这将失败,因为id并不完全相同,但是也许您可以删除前导零。 Try this, perhaps.
试试这个吧。
<xsl:for-each select="Report_Data/Report_Entry">
<xsl:variable name="company_name" select="key('company', number(company_id))" />
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.