XSLT-XPath:用于重新分组元素的每个路径规范 [英] XSLT-XPath: For-each path specification for re-grouping of elements
问题描述
< application>
< contactPerson>
< name> Dominik< / name>
< countryCode> DE< / countryCode>
< / contactPerson>
< contactPerson>
<名称> Dorothea< / name>
< countryCode> DE< / countryCode>
< / contactPerson>
< contactPerson>
< name> Fiona< / name>
< countryCode> FR< / countryCode>
< / contactPerson>
< contactPerson>
< name> Fabian< / name>
< countryCode> FR< / countryCode>
< / contactPerson>
< contactPerson>
<名称> Florian< / name>
< countryCode> FR< / countryCode>
< / contactPerson>
< contactPerson>
< name> Gabi< / name>
< countryCode> GB< / countryCode>
< / contactPerson>
< contactPerson>
<名称> Gert< / name>
< countryCode> GB< / countryCode>
< / contactPerson>
< / application>
现在我想要按照国家来分组元素,这意味着结果应该如下所示:
< application>
< memberState>
< countryCode> De< / countryCode>
< contactPerson>
< name> Dominik< / name>
< / contactPerson>
< contactPerson>
<名称> Dorothea< / name>
< / contactPerson>
< / memberState>
< memberState>
< countryCode> FR< / countryCode>
< contactPerson>
< name> Fiona< / name>
< / contactPerson>
< contactPerson>
< name> Fabian< / name>
< / contactPerson>
< contactPerson>
<名称> Florian< name>
< / contactPerson>
< / memberState>
< memberState>
< countryCode> GB< / countryCode>
< contactPerson>
< name> Gabi< / name>
< / contactPerson>
< contactPerson>
<名称> Gert< / name>
< / contactPerson>
< / memberState>
< / application>
我正在使用XPath for-each模式来选择所有国家,但它不会执行它应该这样做。我的模式如下所示:
< xsl:template match =/>
< application>
< xsl:for-each select =/ application / contactPerson / countryCode [not(。= preceding-sibling :: * / application / contactPerson / countryCode)]>
< memberState>
< countryCode>
< xsl:value-of select =。/>
< / countryCode>
< contactPerson>
< name>
< xsl:value-of select =../ name/>
< / name>
< / contactPerson>
< / memberState>
< / xsl:for-each>
< / application>
< / xsl:template>
该错误可能是XPath表达式中的某处不能编译的。我把它改成了以下内容:
< xsl:for-each select =/ application / contactPerson / countryCode [not(。 =前同辈:: *)]>
因为我觉得我已经在树的正确位置了。这个解决方案编译,但它并没有给我一个独特的国家列表,我打算使用之前的兄弟姐妹,而是完整的清单。
除此之外,我需要我的问题的解决方案,我会特别感谢帮助理解实际发生在这里。
- 有可能给我的第二个解决方案的相对路径,还是我必须给每个完整的路径?
- 我是在正确的轨道上作出一个独特的国家代码列表,或者一般
-
$ b 是否使用XSLT实际实现了解决方案? - Is it possible to give a relative path as in my second solution or do I have to give the complete path each time?
- Am I on the right track for making a unique list of country codes, or would that generally be implemented differently?
- Is the solution I am looking for actually implementable with XSLT?
您的XPath表达式几乎是正确的:
< xsl:for-each
select =/ application / contactPerson / countryCode [not(。= preceding-sibling :: *)]>
不工作的原因是countryCode没有兄弟关系。要找到以前的countryCodes,您需要向上移动一层,然后再移回:
< xsl:for-each
select =/ application / contactPerson / countryCode [not(。= ../preceding-sibling::/countryCode)]\">
我相信应该成功遍历不同的countryCodes。
您对模板的修改应该可以工作。您需要另一个循环遍历每个国家/地区的所有人:
< xsl:template match =/>
< application>
< xsl:for-each select =/ application / contactPerson / countryCode [not(。= .. / preceding-sibling :: * / countryCode)]>
< memberState>
< countryCode>
< xsl:value-of select =。/>
< / countryCode>
< xsl:for-each select =/ application / contactPerson [countryCode = current()]>
< contactPerson>
< name>
< xsl:value-of select =name/>
< / name>
< / contactPerson>
< / xsl:for-each>
< / memberState>
< / xsl:for-each>
< / application>
< / xsl:template>
I have XML documents which I want to transfer into another structure. An example of a document looks as follows:
<application>
<contactPerson>
<name>Dominik</name>
<countryCode>DE</countryCode>
</contactPerson>
<contactPerson>
<name>Dorothea</name>
<countryCode>DE</countryCode>
</contactPerson>
<contactPerson>
<name>Fiona</name>
<countryCode>FR</countryCode>
</contactPerson>
<contactPerson>
<name>Fabian</name>
<countryCode>FR</countryCode>
</contactPerson>
<contactPerson>
<name>Florian</name>
<countryCode>FR</countryCode>
</contactPerson>
<contactPerson>
<name>Gabi</name>
<countryCode>GB</countryCode>
</contactPerson>
<contactPerson>
<name>Gert</name>
<countryCode>GB</countryCode>
</contactPerson>
</application>
Now what I want to do is group the elements by country, meaning the result should look like this:
<application>
<memberState>
<countryCode>De</countryCode>
<contactPerson>
<name>Dominik</name>
</contactPerson>
<contactPerson>
<name>Dorothea</name>
</contactPerson>
</memberState>
<memberState>
<countryCode>FR</countryCode>
<contactPerson>
<name>Fiona</name>
</contactPerson>
<contactPerson>
<name>Fabian</name>
</contactPerson>
<contactPerson>
<name>Florian<name>
</contactPerson>
</memberState>
<memberState>
<countryCode>GB</countryCode>
<contactPerson>
<name>Gabi</name>
</contactPerson>
<contactPerson>
<name>Gert</name>
</contactPerson>
</memberState>
</application>
I am using an XPath for-each pattern to select all countries, but it doesn't do what it is supposed to do. My pattern looks as follows:
<xsl:template match="/">
<application>
<xsl:for-each select="/application/contactPerson/countryCode[not(.=preceding-sibling::*/application/contactPerson/countryCode)]">
<memberState>
<countryCode>
<xsl:value-of select="."/>
</countryCode>
<contactPerson>
<name>
<xsl:value-of select="../name"/>
</name>
</contactPerson>
</memberState>
</xsl:for-each>
</application>
</xsl:template>
The error is probably somewhere in the XPath expression which does not compile. I changed it to the following
<xsl:for-each select="/application/contactPerson/countryCode[not(.=preceding-sibling::*)]">
because I think I am already at the right position of my tree. This solution compiles, but it doesn't give me a unique list of countries as I intended by using "preceding-sibling" but the complete list instead.
Besides that I need the solution to my problem, I would be especially thankful for some help on understanding what is actually happening here.
I appreciate your help very much.
Your XPath expression was almost correct:
<xsl:for-each
select="/application/contactPerson/countryCode[not(.=preceding-sibling::*)]">
The reason it didn't work is that countryCode doesn't have any siblings. To find the previous countryCodes, you need to move up one level and then back down:
<xsl:for-each
select="/application/contactPerson/countryCode[not(. = ../preceding-sibling::*/countryCode)]">
I believe that should successfully iterate through the distinct countryCodes.
This modification to your template should work. You needed another loop to iterate through all the people for each country:
<xsl:template match="/">
<application>
<xsl:for-each select="/application/contactPerson/countryCode[not(.=../preceding-sibling::*/countryCode)]">
<memberState>
<countryCode>
<xsl:value-of select="."/>
</countryCode>
<xsl:for-each select="/application/contactPerson[countryCode = current()]">
<contactPerson>
<name>
<xsl:value-of select="name"/>
</name>
</contactPerson>
</xsl:for-each>
</memberState>
</xsl:for-each>
</application>
</xsl:template>
这篇关于XSLT-XPath:用于重新分组元素的每个路径规范的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!