在XSLT中将XML兄弟标签包裹在一个父标签中

huangapple go评论73阅读模式
英文:

Wrap XML sibling tags in a parent tag with XSLT

问题

I have a set of sibling tags that look like this in a much larger document:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <foo>
  3. <a>some text</a>, '<b>some text</b>', <c><d>some text</d> <e>sometext</e></c>
  4. </foo>

The requirement is that the transform matches tag a followed by ",", followed by tag b, then tag c. These are then wrapped in an outer tag. Below is a simplified representation of what I would like the document to look like:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <foo>
  3. <bar><a>some text</a>, '<b>some text</b>', <c><d>some text</d> <e>sometext</e></c></bar>
  4. </foo>

However, I want this to be done in place in a much larger document without disturbing any other tags.

Basically, I am attempting to match the pattern above in the nodes in the document, then wrap the pattern in a parent tag and delete the old nodes so I do not have duplicates in the output. Is there a way to do that cleanly in XSLT?

英文:

I have a set of sibling tags that look like this in a much larger document:

  1. &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  2. &lt;foo&gt;
  3. &lt;a&gt;some text&lt;/a&gt;, &#39;&lt;b&gt;some text&lt;/b&gt;&#39;, &lt;c&gt;&lt;d&gt;some text&lt;/d&gt; &lt;e&gt;sometext&lt;/e&gt;&lt;/c&gt;
  4. &lt;/foo&gt;

The requirement is that the transform matches tag a followed by "," followed by tag b, then tag c. These are then wrapped in an outer tag. Below is a simplified representation of what I would like the document to look like:

  1. &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  2. &lt;foo&gt;
  3. &lt;bar&gt;&lt;a&gt;some text&lt;/a&gt;, `&lt;b&gt;some text&lt;/b&gt;&#39;, &lt;c&gt;&lt;d&gt;some text&lt;/d&gt; &lt;e&gt;sometext&lt;/e&gt;&lt;/c&gt;&lt;/bar&gt;
  4. &lt;/foo&gt;

However, I want this to be done in place in a much larger document without disturbing any other tags.

Basically, I am attempting to match the pattern above in the nodes in the document then wrap the pattern in a parent tag and delete the old nodes so I do not have duplicates in the output. Is there away to do that cleanly in XSLT?

答案1

得分: 0

这是一个有点奇怪的序列,所以我能够得出的答案是一种有点奇怪的组合,使用了for-each-group group-starting-withfor-each-group group-adjacent(将检查委托给一个函数,你可能需要调整该函数以确切地检查你的节点是否符合预期):

  1. <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  2. xmlns:xs="http://www.w3.org/2001/XMLSchema"
  3. xmlns:mf="http://example.com/mf"
  4. exclude-result-prefixes="#all"
  5. version="3.0">
  6. <xsl:function name="mf:adjacent-predicate" as="xs:boolean">
  7. <xsl:param name="node" as="node()"/>
  8. <xsl:param name="pos" as="xs:integer"/>
  9. <xsl:sequence
  10. select="$pos eq 1 and $node instance of element(a) or
  11. $pos = (2,4) and $node instance of text() and contains($node, ',') or
  12. $pos eq 3 and $node instance of element(b) or
  13. $pos eq 5 and $node instance of element(c)"/>
  14. </xsl:function>
  15. <xsl:mode on-no-match="shallow-copy"/>
  16. <xsl:template match="*[a]">
  17. <xsl:copy>
  18. <xsl:apply-templates select="@*"/>
  19. <xsl:for-each-group select="node()" group-starting-with="a">
  20. <xsl:choose>
  21. <xsl:when test="self::a">
  22. <xsl:for-each-group select="current-group()" group-adjacent="mf:adjacent-predicate(., position())">
  23. <xsl:choose>
  24. <xsl:when test="current-grouping-key()">
  25. <bar>
  26. <xsl:apply-templates select="current-group()"/>
  27. </bar>
  28. </xsl:when>
  29. <xsl:otherwise>
  30. <xsl:apply-templates select="current-group()"/>
  31. </xsl:otherwise>
  32. </xsl:choose>
  33. </xsl:for-each-group>
  34. </xsl:when>
  35. <xsl:otherwise>
  36. <xsl:apply-templates select="current-group()"/>
  37. </xsl:otherwise>
  38. </xsl:choose>
  39. </xsl:for-each-group>
  40. </xsl:copy>
  41. </xsl:template>
  42. </xsl:stylesheet>
英文:

It is kind of an odd sequence so all I have been able to come with is a bit of an odd combination of a for-each-group group-starting-with plus for-each-group group-adjacent (delegating the check to a function you probably need to adjust to check your nodes exactly as you expect them):

  1. &lt;xsl:stylesheet xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;
  2. xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot;
  3. xmlns:mf=&quot;http://example.com/mf&quot;
  4. exclude-result-prefixes=&quot;#all&quot;
  5. version=&quot;3.0&quot;&gt;
  6. &lt;xsl:function name=&quot;mf:adjacent-predicate&quot; as=&quot;xs:boolean&quot;&gt;
  7. &lt;xsl:param name=&quot;node&quot; as=&quot;node()&quot;/&gt;
  8. &lt;xsl:param name=&quot;pos&quot; as=&quot;xs:integer&quot;/&gt;
  9. &lt;xsl:sequence
  10. select=&quot;$pos eq 1 and $node instance of element(a) or
  11. $pos = (2,4) and $node instance of text() and contains($node, &#39;,&#39;) or
  12. $pos eq 3 and $node instance of element(b) or
  13. $pos eq 5 and $node instance of element(c)&quot;/&gt;
  14. &lt;/xsl:function&gt;
  15. &lt;xsl:mode on-no-match=&quot;shallow-copy&quot;/&gt;
  16. &lt;xsl:template match=&quot;*[a]&quot;&gt;
  17. &lt;xsl:copy&gt;
  18. &lt;xsl:apply-templates select=&quot;@*&quot;/&gt;
  19. &lt;xsl:for-each-group select=&quot;node()&quot; group-starting-with=&quot;a&quot;&gt;
  20. &lt;xsl:choose&gt;
  21. &lt;xsl:when test=&quot;self::a&quot;&gt;
  22. &lt;xsl:for-each-group select=&quot;current-group()&quot; group-adjacent=&quot;mf:adjacent-predicate(., position())&quot;&gt;
  23. &lt;xsl:choose&gt;
  24. &lt;xsl:when test=&quot;current-grouping-key()&quot;&gt;
  25. &lt;bar&gt;
  26. &lt;xsl:apply-templates select=&quot;current-group()&quot;/&gt;
  27. &lt;/bar&gt;
  28. &lt;/xsl:when&gt;
  29. &lt;xsl:otherwise&gt;
  30. &lt;xsl:apply-templates select=&quot;current-group()&quot;/&gt;
  31. &lt;/xsl:otherwise&gt;
  32. &lt;/xsl:choose&gt;
  33. &lt;/xsl:for-each-group&gt;
  34. &lt;/xsl:when&gt;
  35. &lt;xsl:otherwise&gt;
  36. &lt;xsl:apply-templates select=&quot;current-group()&quot;/&gt;
  37. &lt;/xsl:otherwise&gt;
  38. &lt;/xsl:choose&gt;
  39. &lt;/xsl:for-each-group&gt;
  40. &lt;/xsl:copy&gt;
  41. &lt;/xsl:template&gt;
  42. &lt;/xsl:stylesheet&gt;

huangapple
  • 本文由 发表于 2023年2月24日 04:30:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75550015.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定