XSLT:我可以使用 xslt 更新 xml 节点中的值吗?

发布于 2024-10-24 05:51:50 字数 348 浏览 1 评论 0原文

例如,我有一个 xml

 <books>
   <book id="1">
     <title id="11" name="Basic XML"/>
     <price id="12" amount="500"/>
     <quantity id="13" number="10"/>
   </book>
 </books>

可以将书名“Basic XML”更新为“Basic XSLT”或使用 XSLT 更改任何节点的任何其他属性吗?如果是,有人可以给我一些关于如何做到这一点的例子吗?

提前致谢。

For example I have a xml like

 <books>
   <book id="1">
     <title id="11" name="Basic XML"/>
     <price id="12" amount="500"/>
     <quantity id="13" number="10"/>
   </book>
 </books>

Can update the name of the book "Basic XML" to "Basic XSLT" or change any other attributes of any node using XSLT? If yes, can anyone give me some examples on how to do it?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

巴黎夜雨 2024-10-31 05:51:50

此转换

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <my:reps>
  <repAttr name="name" value="Basic XSLT"/>
  <repAttr name="amount" value="300"/>
  <repAttr name="number" value="20"/>
 </my:reps>

 <xsl:strip-space elements="*"/>

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

 <xsl:template match=
   "@*[name()=document('')/*/my:reps/*/@name]">

   <xsl:attribute name="{name()}">
    <xsl:value-of select=
    "document('')/*/my:reps/*[@name=name(current())]/@value"/>
   </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时:

<books>
    <book id="1">
        <title id="11" name="Basic XML"/>
        <price id="12" amount="500"/>
        <quantity id="13" number="10"/>
    </book>
</books>

产生所需的正确结果:

<books>
   <book id="1">
      <title id="11" name="Basic XSLT"/>
      <price id="12" amount="300"/>
      <quantity id="13" number="20"/>
   </book>
</books>

说明

  1. 身份规则/模板“按原样”复制每个节点。

  2. 身份模板由与任何属性匹配的单个模板覆盖,该属性的名称可以作为在中指定的 repAttr 元素的 name 属性之一的值找到。 my:reps 元素(嵌入 XSLT 样式表中的参数)。

  3. 在这种情况下,将使用相同的名称和新值重新创建(而不是复制)该属性,该值在相应的 repAttr 元素(其 value 属性)中指定)。

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <my:reps>
  <repAttr name="name" value="Basic XSLT"/>
  <repAttr name="amount" value="300"/>
  <repAttr name="number" value="20"/>
 </my:reps>

 <xsl:strip-space elements="*"/>

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

 <xsl:template match=
   "@*[name()=document('')/*/my:reps/*/@name]">

   <xsl:attribute name="{name()}">
    <xsl:value-of select=
    "document('')/*/my:reps/*[@name=name(current())]/@value"/>
   </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<books>
    <book id="1">
        <title id="11" name="Basic XML"/>
        <price id="12" amount="500"/>
        <quantity id="13" number="10"/>
    </book>
</books>

produces the wanted, correct result:

<books>
   <book id="1">
      <title id="11" name="Basic XSLT"/>
      <price id="12" amount="300"/>
      <quantity id="13" number="20"/>
   </book>
</books>

Explanation:

  1. The identity rule/template copies every node "as-is".

  2. The identity template is overriden by a single template matching any attribute whose name can be found as value of one of the name attributes of a repAttr element that is specified in the my:reps element (parameters embeded in the XSLT stylesheet).

  3. In this case the attribute is re-created (not copied) with the same name and with the new value, specified in the corresponding repAttr element (its value attribute).

╄→承喏 2024-10-31 05:51:50

我无法“更新”输入 Xml,因为 XSLT 纯粹是一种输出驱动技术。它会创建一份新文档,并且无法修改现有文档。

您可以制作几乎相同的副本,但正如 @Oded 评论指出的那样,XSLT 可能有点过分了。 xsl 看起来像(修改后的身份转换)

<xsl:stylesheet version="1.0">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
   <xsl:template match="title/@Name">
     <!-- insert logic here to change the value as appropriate -->
   </xsl:template>
</xsl:stylesheet>

I cannot "update" the input Xml as XSLT is purely an output driven technology. It creates anew document and cannot modify the existing one.

You could make an almost identical copy but as @Oded comment points out XSLT may be overkill. The xsl would look something like (a modified identity transform)

<xsl:stylesheet version="1.0">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
   <xsl:template match="title/@Name">
     <!-- insert logic here to change the value as appropriate -->
   </xsl:template>
</xsl:stylesheet>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文