xml - 将元素的单个 XML 属性转换为子元素
问题描述
首先,我想对所有了解 XSLT 处理情况的人表示钦佩。
通常,我会在 StackOverflow 上找到一些满足我需要的示例,稍微调整一下,然后继续使用 C 编码:),但这次我被卡住了,不明白为什么事情不工作。
我对其进行了修改以处理我需要的单个属性,并且它与原始问题中的 XML 示例一起按预期工作。
即我可以得到:
<sect id="5" heading="1">
</sect>
修改为:
<sect heading="1">
<id>5</id>
</sect>
在这里使用示例
但是我的 XML 有点复杂,到目前为止发现了 2 个问题来处理它(都在上面的链接中给出):
- 我希望新元素首先放在原始元素之后,但是如果自由文本出现在原始元素之后,结果会有所不同,即新元素将在文本之后。
- 处理我修改的元素时出现问题,例如:
<TableCell>User input and actions: for example, type <bold>exit</bold>, click <bold>OK</bold>, press <bold>Alt+C</bold></TableCell>
将改为
<TableCell>User input and actions: for example, type , click , press <bold>exit</bold><bold>OK</bold><bold>Alt+C</bold></TableCell>
如果将同一行放在具有我正在修改的属性的元素之外,则它保持不变。仔细观察第二个问题,它似乎与第一个问题相同或相似,即自由文本放在元素之前,并且不保留原始顺序。
由于我无法理解 XSLT 中的处理顺序,我不知道如何修复它。对此或完全替代建议的任何帮助将不胜感激。
问候,伊利亚。
解决方案
首先将要复制的属性作为属性与一个应用模板(或简单地使用它们的副本)处理就足够了,然后将模板应用到 id 属性和任何子节点:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*[not(name()='id')]"/>
<xsl:apply-templates select="@id | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@id">
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
推荐阅读
- python - 如何在某些事件上从容器向主机发送信号?
- c# - 运行 'dotnet build' 时 StyleCop 忽略 GlobalSuppressions,用错误消息淹没 CI,直到它终止
- javascript - 无法从 aws lambda (java) 读取 json 正文响应。它说可读流
- reactjs - 使用 react 创建 js Webpack 配置
- python - 简化 re.compile 以匹配任何长字符
- javascript - 在 NodeRed 中使用 clearInterval
- linux - 如何解决 Linux 和 Modbus 的错误文件描述符
- java - 为谢尔宾斯基法打印三角形时如何固定三角形位置
- java - 反序列化时如何正确使用瞬态关键字?
- java - 在 Jetty 的 webapp 中重新加载类