我正在使用XSLT 1.0转换以XML格式存储的医疗记录数据。因为这些是患者记录,虽然可以调整某些文本值,但没有任何东西可以删除,所以我必须从身份模板开始。
我需要根据逻辑条件调整某些节点的文本内容,例如包含最多10个不同ID号中的任何一个的另一个兄弟节点。我尝试使用谓词进行过滤,并且,由于它在 XSLT Cookbook 的第4章中提到,我尝试将For-Each
应用于其所谓的更快“选择”方法,而不是基于Choose-When
逻辑的“过滤”方法。我发现Match与谓词之间的差异和使用For-Each的Select与谓词可以忽略不计。我非常愿意使用Keys,但我不太确定如何应用它来帮助解决我的问题。
我有两个主要问题:
至关重要的是,我找到最有效的匹配方式并调整符合条件的节点文本。我们在处理和记录检索时间方面遇到严重延误。如果我能找到一个最佳的解决方案,那么我可以在多个地方重新编写旧的XSLT模板并真正改进。
我有这样的XML:
<Facilities>
<Facility>XYZ</Facility>
<Records>
<!-- lots and lots of other kinds of records here A to Z, long XML before this. -->
<!-- RecordAAA #1 -->
<RecordAAA>
<Item>
<number>123</number>
<definition>123 really means this</definition>
</Item>
<ItemCategory>
<ID>AAA</ID>
<IdDescription>AAA</IdDescription>
</ItemCategory>
</RecordAAA>
<!-- RecordAAA #2 -->
<RecordAAA>
<Item>
<number>456</number>
<definition>456 really means this</definition>
</Item>
<ItemCategory>
<ID>AAA</ID>
<IdDescription>AAA</IdDescription>
</ItemCategory>
</RecordAAA>
<!-- RecordAAA #3 -->
<RecordAAA>
<Item>
<number>123</number>
<definition>123 really means this</definition>
</Item>
<ItemCategory>
<ID>AAA</ID>
<IdDescription>AAA</IdDescription>
</ItemCategory>
</RecordAAA>
<!-- lots and lots of other kinds of records here A to Z, long XML after this. -->
</Records>
</Facilities>
所需输出:<ItemCategory> <ID>
和<ItemCategory> <IdDescription>
内容根据RecordAAA#2的项目/数字文本为'456'而更改,
而RecordAAA#1和#3只是复制过来:
<Facilities>
<Facility>XYZ</Facility>
<Records>
<!-- lots and lots of other kinds of records here A to Z, long XML, before this. -->
<!-- RecordAAA #1 -->
<RecordAAA>
<Item>
<number>123</number>
<definition>123 really means this</definition>
</Item>
<ItemCategory>
<ID>AAA</ID>
<IdDescription>AAA</IdDescription>
</ItemCategory>
</RecordAAA>
<!-- RecordAAA #2 -->
<RecordAAA>
<Item>
<number>456</number>
<definition>456 really means this</definition>
</Item>
<!-- ID and IdDescription have been changed. -->
<ItemCategory>
<ID>BBB</ID>
<IdDescription>BBB</IdDescription>
</ItemCategory>
</RecordAAA>
<!-- RecordAAA #3 -->
<RecordAAA>
<Item>
<number>123</number>
<definition>123 really means this</definition>
</Item>
<ItemCategory>
<ID>AAA</ID>
<IdDescription>AAA</IdDescription>
</ItemCategory>
</RecordAAA>
<!-- lots and lots of other kinds of records here A to Z, long XML, after this. -->
</Records>
</Facilities>
我有这样的XSLT模板,当然这有效:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Identity template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Records/RecordAAA[Item/number='456' or Item/number='789' or Item/number='101112']/ItemCategory">
<ItemCategory>
<ID>BBB</ID>
<IdDescription>BBB</IdDescription>
</ItemCategory>
</xsl:template>
</xsl:stylesheet>
但如果我有更多代码的工具,我该怎么办呢?它开始看起来像这样:
<xsl:template match="Records/RecordAAA[Item/number='456'
or Item/number='789'
or Item/number='101112'
or Item/number='1314'
or Item/number='1516'
or Item/number='1718'
or Item/number='1920'
or Item/number='2122'
or Item/number='2324'
or Item/number='2526'
or Item/number='2728']/ItemCategory">
<ItemCategory>
<ID>BBB</ID>
<IdDescription>BBB</IdDescription>
</ItemCategory>
</xsl:template>
这仍然可以创建所需的输出(就像一系列Choose-When
条件一样)但是如何才能更快地完成?有没有办法真正提高效率?
如果对你的答案很重要,我们正在使用Xalan处理器而且我坚持使用版本1.0。
非常感谢您提供任何可靠的见解。
答案 0 :(得分:1)
我不确定你能否更快地进行这些比较。
您可以通过在参数或单独文件中保留设施列表来使代码更清晰。
这是一个示例XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name='facilityfile'>fax.xml</xsl:param>
<xsl:variable name='facility' select='document($facilityfile)//facility/@nbr'/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--
<xsl:template match="Records/RecordAAA[Item/number='456' or Item/number='789' or Item/number='101112']/ItemCategory">
-->
<xsl:template match='ItemCategory'>
<xsl:choose>
<xsl:when test='preceding-sibling::Item/number=$facility'>
<ItemCategory>
<ID>BBB</ID>
<IdDescription>BBB</IdDescription>
</ItemCategory>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
和设施fax.xml内容
<xml>
<facility nbr='456'/>
<facility nbr='567'/>
<facility nbr='678'/>
<facility nbr='789'/>
</xml>
答案 1 :(得分:0)
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<!-- generate-id(../..) returns the id of the grandparent of number. ie. RecordAAA -->
<xsl:key name="myKey" match="number[.='456' or .='789' or .='101112']" use="generate-id(../..)"/>
<!-- Identity template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- generate-id(..) returns the parent of ItemCategory. ie. RecordAAA-->
<xsl:template match="ItemCategory[key('myKey', generate-id(..))]">
<ItemCategory>
<ID>BBB</ID>
<IdDescription>BBB</IdDescription>
</ItemCategory>
</xsl:template>
</xsl:stylesheet>