
本教程详细介绍了如何使用XSLT高效且精确地重构XML数据结构,解决将特定元素(如`
在处理复杂的XML数据时,我们经常需要调整其内部结构,以满足不同的业务或集成需求。一个常见的场景是将某个元素从其当前位置移动到另一个逻辑相关的元素内部,同时保持数据关联性。例如,将原本位于WarehouseHeader层级的zuojiankuohaophpcnQuantity>元素移动到其对应的WarehouseLine内部。
考虑以下XML结构,其中<Quantity>元素直接位于<WarehouseHeader>下,而我们希望它能作为其紧邻的<WarehouseLine>的子元素:
<?xml version="1.0"?>
<Container xmlns:ti="http://www.to-increase.com/data/blocks">
<WarehouseHeader>
<No>RMA-21001</No>
<Description>RMA t.b.v. order_id #2</Description>
<Duedate>17/11/2021</Duedate>
<Quantity>1</Quantity>
<WarehouseLine>
<ItemNo>7890</ItemNo>
<Description>Radiant Tee-L-Purple</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
</WarehouseLine>
</WarehouseHeader>
<WarehouseHeader>
<No>RMA-21003</No>
<Description>RMA t.b.v. order_id #32</Description>
<Duedate>02/12/2021</Duedate>
<Quantity>1</Quantity> <!-- 第一个Quantity -->
<WarehouseLine>
<ItemNo>4560</ItemNo>
<Description>Strive Shoulder Pack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
</WarehouseLine>
<Quantity>8</Quantity> <!-- 第二个Quantity -->
<WarehouseLine>
<ItemNo>1234</ItemNo>
<Description>Driven Backpack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
</WarehouseLine>
</WarehouseHeader>
</Container>我们期望的输出结构是每个<WarehouseLine>都包含一个对应的<Quantity>子元素,并且原有的<WarehouseHeader>下的<Quantity>元素被移除:
<?xml version="1.0"?>
<Container xmlns:ti="http://www.to-increase.com/data/blocks">
<WarehouseHeader>
<No>RMA-21001</No>
<Description>RMA t.b.v. order_id #2</Description>
<Duedate>17/11/2021</Duedate>
<WarehouseLine>
<ItemNo>7890</ItemNo>
<Description>Radiant Tee-L-Purple</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>1</Quantity>
</WarehouseLine>
</WarehouseHeader>
<WarehouseHeader>
<No>RMA-21003</No>
<Description>RMA t.b.v. order_id #32</Duedate>
<WarehouseLine>
<ItemNo>4560</ItemNo>
<Description>Strive Shoulder Pack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>1</Quantity>
</WarehouseLine>
<WarehouseLine>
<ItemNo>1234</ItemNo>
<Description>Driven Backpack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>8</Quantity>
</WarehouseLine>
</WarehouseHeader>
</Container>直接使用编程语言(如PHP的SimpleXML)进行操作时,如果WarehouseHeader下存在多个Quantity和WarehouseLine对,可能会遇到难以精确关联的问题。例如,简单地遍历WarehouseHeader并复制第一个Quantity到所有WarehouseLine,会导致所有行都获得相同的数量,或者难以正确匹配到紧邻的Quantity。这种情况下,XSLT(Extensible Stylesheet Language Transformations)提供了一种声明式、更强大的解决方案。
XSLT是一种专门用于将XML文档转换为其他XML文档、HTML文档或纯文本的语言。它通过定义一系列模板来匹配输入XML文档中的节点,并指定如何将这些节点转换为输出。其优势在于:
对于上述问题,XSLT的解决方案核心在于两步:
以下是实现所需转换的XSLT样式表:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ti="http://www.to-increase.com/data/blocks">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<!-- 恒等转换模板:复制所有未被其他模板匹配的节点和属性 -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- 抑制WarehouseHeader下的Quantity元素 -->
<xsl:template match="WarehouseHeader/Quantity"/>
<!-- 将紧邻的Quantity元素移动到WarehouseLine内部 -->
<xsl:template match="WarehouseLine">
<xsl:copy>
<xsl:copy-of select="*"/> <!-- 复制WarehouseLine自身的所有子元素 -->
<xsl:copy-of select="preceding-sibling::Quantity[1]"/> <!-- 复制紧邻前一个兄弟Quantity元素 -->
</xsl:copy>
</xsl:template>
</xsl:stylesheet><xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>这是XSLT中一个非常常用的模板,称为“恒等转换”或“复制所有”。它的作用是:
这个模板确保了输入XML中所有未被其他更具体模板匹配的元素和属性都会被原样复制到输出中,从而避免了手动为每个不需要修改的元素编写复制规则。
<xsl:template match="WarehouseHeader/Quantity"/>
这个模板匹配所有直接位于WarehouseHeader下的Quantity元素。由于模板体为空,当XSLT处理器遇到这些Quantity元素时,不会生成任何输出,从而实现了“删除”或“抑制”这些元素的效果。
<xsl:template match="WarehouseLine">
<xsl:copy>
<xsl:copy-of select="*"/>
<xsl:copy-of select="preceding-sibling::Quantity[1]"/>
</xsl:copy>
</xsl:template>这是实现元素移动的关键模板:
通过这种方式,每个WarehouseLine元素都能准确地找到并复制其在源文档中紧邻的Quantity值,从而实现了精确的元素移动和关联。
将上述XSLT样式表应用于提供的输入XML,将生成以下输出XML,完美符合预期:
<Container xmlns:ti="http://www.to-increase.com/data/blocks">
<WarehouseHeader>
<No>RMA-21001</No>
<Description>RMA t.b.v. order_id #2</Description>
<Duedate>17/11/2021</Duedate>
<WarehouseLine>
<ItemNo>7890</ItemNo>
<Description>Radiant Tee-L-Purple</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>1</Quantity>
</WarehouseLine>
</WarehouseHeader>
<WarehouseHeader>
<No>RMA-21003</No>
<Description>RMA t.b.v. order_id #32</Description>
<Duedate>02/12/2021</Duedate>
<WarehouseLine>
<ItemNo>4560</ItemNo>
<Description>Strive Shoulder Pack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>1</Quantity>
</WarehouseLine>
<WarehouseLine>
<ItemNo>1234</ItemNo>
<Description>Driven Backpack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>8</Quantity>
</WarehouseLine>
</WarehouseHeader>
</Container>通过本教程,我们学习了如何利用XSLT的声明式特性、强大的XPath表达式和模板匹配机制,高效且精确地重构XML数据结构。相较于过程式编程方法,XSLT在处理此类XML转换任务时展现出更高的灵活性和可维护性,尤其适用于需要根据复杂规则调整XML层级关系的场景。掌握XSLT能够显著提升XML数据处理的效率和质量。
以上就是XML元素重构:利用XSLT实现精确层级调整的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号