ADO XML 使用 XSL 样式表清理

ADO XML cleanup using XSL stylesheet

我不得不升级我的 XSL 样式表名称空间,我用它来从 http://www.w3.org/TR/WD-xsl to http://www.w3.org/1999/XSL/Transform 中“清理”ADO XML - 现在使用该样式表不提供与以前相同的输出,因此中断功能。

我尝试了多种组合,但其中 none 提供了与以前相同的结果 - 我是 XSL 的新手。你能帮忙吗?

我正在使用 MSXML2.DOMDocument60.transformNodeToObject 作为 VB 中的 API 来应用样式表。

这是我的输入 ADO XML:

<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
xmlns:rs="urn:schemas-microsoft-com:rowset"
xmlns:z="#RowsetSchema">
  <s:Schema id="RowsetSchema">
    <s:ElementType name="row" content="eltOnly" rs:updatable="true">
      <s:AttributeType name="ShipperID" rs:number="1"
        rs:basetable="shippers" rs:basecolumn="ShipperID"
        rs:keycolumn="true">
        <s:datatype dt:type="int" dt:maxLength="4" rs:precision="10"
          rs:fixedlength="true" rs:maybenull="false"/>
      </s:AttributeType>
      <s:AttributeType name="CompanyName" rs:number="2"
        rs:nullable="true" rs:write="true" rs:basetable="shippers"
        rs:basecolumn="CompanyName">
        <s:datatype dt:type="string" dt:maxLength="40" />
      </s:AttributeType>
      <s:AttributeType name="Phone" rs:number="3" rs:nullable="true"
        rs:write="true" rs:basetable="shippers"
        rs:basecolumn="Phone">
        <s:datatype dt:type="string" dt:maxLength="24"/>
      </s:AttributeType>
      <s:extends type="rs:rowbase"/>
    </s:ElementType>
  </s:Schema>
  <rs:data>
    <rs:insert>
      <z:row ShipperID="1" CompanyName="Speedy Express" Phone="(503) 111-4567"/>
      <z:row ShipperID="2" CompanyName="United Package" Phone="(503) 222-4567"/>
      <z:row ShipperID="3" CompanyName="Federal Shipping" Phone="(503) 333-4567"/>
    </rs:insert>
  </rs:data>
</xml>

这是有效的旧样式表:

<?xml version='1.0'?>                                       
<stylesheet xmlns='http://www.w3.org/TR/WD-xsl'>
  <template>
    <copy>
      <apply-templates select="@* | * | comment() | pi() | text()"/>
    </copy>
  </template>
  <template match="rs:insert" >
    <apply-templates select="@* | * | comment() | pi() | text()"/>
  </template>
  <template match="rs:data" >
    <element name="data">
      <apply-templates select="@* | * | comment() | pi() | text()"/>
    </element>
  </template>
  <template match="z:row" >
    <element name="row">
      <apply-templates select="@* | * | comment() | pi() | text()"/>
    </element>
  </template>
  <template match="@rs:forcenull" >
    <attribute name="forcenull"/>
  </template>
  <template match="s:Schema" />
  <template match="@xmlns:s" />
  <template match="@xmlns:dt" />
  <template match="@xmlns:rs" />
  <template match="@xmlns:z" />
</stylesheet>

这是我之前得到的结果,也是我现在需要的:

<xml>
  <data>
      <row ShipperID="1" CompanyName="Speedy Express" Phone="(503) 111-4567"></row>
      <row ShipperID="2" CompanyName="United Package" Phone="(503) 222-4567"></row>
      <row ShipperID="3" CompanyName="Federal Shipping" Phone="(503) 333-4567"></row>
  </data>
</xml>

这是新样式表(进行中):

<?xml version="1.0" encoding="UTF-8"?>
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version = "3.0"
 xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
  <template match="/">
    <copy>
      <apply-templates select="@* | * | comment() | processing-instruction() | text()" />
    </copy>
  </template>
  <template match="rs:insert">
      <apply-templates select="@* | * | comment() | processing-instruction() | text()"/>
  </template>
  <template match="rs:data">
    <element name="data">
      <apply-templates select="@* | * | comment() | processing-instruction() | text()"/>
    </element>
  </template>
  <template match="z:row">
    <element name="row">
      <copy-of select="@* | * | comment() | processing-instruction() | text()"/>
    </element>
  </template>
  <template match="@rs:forcenull" >
    <attribute name="forcenull"/>
  </template>
  <template match="s:Schema"/>
  <template match="@xmlns:s"/>
  <template match="@xmlns:dt"/>
  <template match="@xmlns:rs"/>
  <template match="@xmlns:z"/>
</stylesheet>

这是我现在得到的结果(错误,与之前不是 100% 相同):

<?xml version="1.0" encoding="UTF-16"?>
<data xmlns="http://www.w3.org/1999/XSL/Transform">
  <row ShipperID="1" CompanyName="Speedy Express" Phone="(503) 111-4567"></row>
  <row ShipperID="2" CompanyName="United Package" Phone="(503) 222-4567"></row>
  <row ShipperID="3" CompanyName="Federal Shipping" Phone="(503) 333-4567"></row>
</data>

基本上给定输入 ADO XML - 我希望执行以下操作:

  1. 删除所有名称空间信息架构等但保留打开和关闭标记(部分完成)
  2. <rs:data> 需要变成没有任何属性的 <data>(如何从数据的 xmlns 中删除该属性?)
  3. <rs:insert> 需要消失(完成)
  4. <z:row> 需要变成 <row>(完成)

输入数据可能会有所不同,但结构相同 - 这就是我像以前一样需要一组通用规则的原因。

如果您需要删除命名空间,请使用

<xsl:template match="*">
  <xsl:element name="{local-name()}">
    <xsl:apply-templates select="@* | node()"/>
  </xsl:element>
</xsl:template>

<xsl:template match="@*">
  <xsl:attribute name="{local-name()}">
    <xsl:value-of select="."/>
  </xsl:attribute>
</xsl:template>

作为基本模板。

然后

<xsl:template match="rs:insert">
  <xsl:apply-templates/>
</xsl:template>

对于名称更改,例如

<xsl:template match="z:row">
  <row>
    <xsl:apply-templates select="@* | node()"/>
  </row>
</xsl:template>

确保使用例如exclude-result-prefixes="z rs" 在 XSLT 中声明的任何名称空间的 xsl:stylesheet 元素上,只是输入中的 select 元素或属性,但您不希望名称空间出现在结果中。

不要搬起石头砸自己的脚,将 XSLT 代码放入默认命名空间,因此请使用例如

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version = "1.0"
 xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
 xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema" exclude-result-prefixes="z s rs">

<xsl:template match="*">
  <xsl:element name="{local-name()}">
    <xsl:apply-templates select="@* | node()"/>
  </xsl:element>
</xsl:template>


<xsl:template match="@*">
  <xsl:attribute name="{local-name()}">
    <xsl:value-of select="."/>
  </xsl:attribute>
</xsl:template>


<xsl:template match="rs:insert | xml">
  <xsl:apply-templates/>
</xsl:template>


<xsl:template match="z:row">
  <row>
    <xsl:apply-templates select="@* | node()"/>
  </row>
</xsl:template>

<xsl:template match="s:Schema"/>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/jxWZS8g/1