xml - An XSL file that processes several XML files
问题描述
I need an XSL file that reads several XML files and applies the same transformation to each. So far I've got this (sanitized version):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="document('first_xml_file.xml')">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="//outer_tag/inner_tag">
...stuff to appear in output for each file...
<xsl:for-each select="outer_tag/inner_tag">
...stuff to appear in output for each inner_tag...
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
The strategy being that once it works I can add more <template> blocks to process more files.
Because a transformation tool always wants an XML file to work on, I created an empty XML file:
<?xml version="1.0"?>
<nothing/>
Then I ran Microsoft's transformation tool and got:
C:\...>msxsl empty.xml my_style_sheet.xsl
Error occurred while compiling stylesheet 'my_style_sheet.xsl'.
Code: 0x80004005
NodeTest expected here.
-->document<--('first_xml_file.xml')
C:...>
I looked this up and found that the only functions allowed in a pattern are id() and key(). That precludes the use of document() -- and makes it impossible to write an XSL file that reads several XML files, at least the way I want to do it. What is the solution here?
解决方案
通常的(至少在 XSLT 1 中)和工作方法是match="/*"
使用您的原始输入,然后使用<xsl:apply-templates select="document('doc1.xml') | document('doc2.xml') | document('doc3.xml')"/>
或将主要输入作为具有辅助 XML 文件 url 的源,然后您将在其中使用<xsl:apply-templates select="document(files/file)"/>
例如<files><file>doc1.xml</file><file>doc2.xml</file><file>doc3.xml</file></files>
作为内容主要输入。
然后,您将编写与那些引用文件中的元素匹配的模板,而不是在任何文档节点上进行匹配。唯一的问题是您可能需要使用模式来确保您可以区分主文档的根节点或根元素和辅助文档的根或元素。这取决于文档的结构和模板的组织。
一般来说,您的两种匹配模式似乎都很不寻常,match="//outer_tag/inner_tag"
也可以缩短为match="outer_tag/inner_tag"
不产生任何语义差异。
并且match="document('first_xml_file.xml')"
可能会写成match="document-node()[. is document('first_xml_file.xml')]"
您的目标是真正识别该特定文档。无论如何,该语法是 XSLT 2,因此它对 MSXML 没有帮助。
XSLT 2/3 更加灵活和强大,无论是在匹配模式的可能性方面,还是通过使用collection
和/或之类的函数uri-collection
。XSLT 2 或 3 可在 Windows 上通过使用 Saxon 9 HE 的 Java 或 .NET 版本的命令行获得。
推荐阅读
- r - 将时间序列分组为分层数据
- symfony5 - 在新用户的表单中使用密码编码器
- r - 在用户定义函数中调用 colnames()
- mysql - 如何只选择一个值的前 2 个寄存器?
- javascript - 如何解决这种意外混合的“>>>”和“&”运算符警告?
- c# - 列表
- > 达到内存限制
- cypress - 赛普拉斯:赛普拉斯无法找到边缘
- python - 在本地运行 Pyspark 以访问 S3 中的 parquet 文件错误:“无法从链中的任何提供商加载 AWS 凭证”
- powershell - 如何使用 powershell 自定义日期获得与某个日期的年月差?
- java - 在回调内部的 onResponse 方法中获取传递给改造的查询参数