不能在“根”类型的节点中构造“属性”类型的项目

Posted

技术标签:

【中文标题】不能在“根”类型的节点中构造“属性”类型的项目【英文标题】:An item of type 'Attribute' cannot be constructed within a node of type 'Root 【发布时间】:2013-09-07 01:49:03 【问题描述】:

我试图弄清楚如何将属性添加到根节点。我有以下 xslt 来转换两种不同类型的 xml 文件。第一个 xml 文件转换得很好我有问题当它的第二个 xml 文件我的 xslt 抛出错误“无法在 'Root 类型的节点中构造'属性'类型的项目”我如何在 xslt 中解决这个问题

XSLT 文件

<?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"/>

  <!--Check whether lossformsVersion exists If not write-->
  <xsl:template match="Inspection[not(@lossFormsVersion)]">
    <xsl:attribute name="lossFormsVersion">07-25-2013-1-54</xsl:attribute>
  </xsl:template>

  <!--Replace the lossformsVersion with this templates version-->
  <xsl:template match="Inspection/@lossFormsVersion">
    <xsl:attribute name="lossFormsVersion">07-25-2013-1-54</xsl:attribute>
  </xsl:template>

  <!--Copy the rest of the document as it is-->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

第一个 XML 文件(转换前)

<?xml version="1.0" encoding="utf-8" ?>
<Inspection lossFormsVersion="07-25-2013-1-52">
.
.
.
</Inspection>

第一个 XML 文件(转换后)

<?xml version="1.0" encoding="utf-8" ?>
<Inspection lossFormsVersion="07-25-2013-1-54">
.
.
.
</Inspection>

第二个 XML 文件(转换前)

<?xml version="1.0" encoding="utf-8" ?>
<Inspection>
.
.
.
</Inspection>

转换后的第二个 XML 文件应该看起来与第一个转换后的 XML 文件完全相同。提前致谢

【问题讨论】:

在您的第一个模板中,您匹配了根节点,但没有写出元素节点。您试图输出未附加到元素的“裸”属性节点。 【参考方案1】:
<xsl:template match="Inspection[not(@lossFormsVersion)]">
    <xsl:copy>
        <xsl:attribute name="lossFormsVersion">07-25-2013-1-54</xsl:attribute>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

对于第二个 xml,您的模板与您将属性写入输出的元素相匹配。 xsl:copy 复制 Ïnspection 节点并将属性写入该节点。

【讨论】:

谢谢GP。这解决了问题。非常感谢您的帮助【参考方案2】:

你可能认为这两种匹配模式

match = "Inspection [not(@lossFormsVersion)]"

match = "Inspection / @lossFormsVersion" 

是平行的;如果它们是平行的,那么您观察到的行为确实会令人惊讶。

但它们不是平行的,您越早掌握如何以及为什么,您就会越早熟悉 XPath 和基于 XPath 的语言。第一个模式匹配元素类型名称为Inspection 且没有lossFormsVersion 属性的元素。第二个模式匹配位于Inspection 属性上名为lossFormsVersion属性

一旦你清楚了这一点,gp 提供的答案的逻辑就应该清楚了。

【讨论】:

以上是关于不能在“根”类型的节点中构造“属性”类型的项目的主要内容,如果未能解决你的问题,请参考以下文章

DOM

JS 判断节点类型

dynamic 类型不能访问属性

二叉树感悟

xpath语法与lxml库

Vue3+TypeScript项目报错: 找不到名称“require”。是否需要为节点安装类型定义?