簡體   English   中英

XSLT更新屬性,僅賦予新值和屬性的XPath

[英]XSLT to update an attribute given just the new value and XPath to the attribute

我有一些代碼比較兩個XML文檔的屬性差異(僅更新,而不是新的屬性節點),並生成一組指向該屬性的XPath指針和該屬性的新值。

設置

例如,給定舊的XML和新的xml:

舊的XML

<EntityA>
  <EntityB id="foo1" value="bar1" ignoredbutsave="bazz1"/>
</EntityA>

新的XML

<EntityA>
  <EntityB id="foo2" value="bar2"/>
</EntityA>

我的代碼會返回

/EntityA/EntityB/@id, foo2
/EntityA/EntityB/@value, bar2

我想生成一個XSLT,它將舊的XML合並為新的XML,以創建以下XML:

<EntityA>
  <EntityB id="foo2" value="bar2" ignoredbutsave="bazz1"/>
</EntityA>

我在SO上找到的所有答案都假定具有有關屬性名稱的一些先驗知識。 在這種情況下,我僅給XPath引用賦予屬性,而不給名稱本身。 我知道我可以解析XPath字符串以派生屬性名稱,但是希望將這種復雜性排除在代碼之外。

我嘗試過的

我無法使用屬性值模板,因為我需要從舊的XML中復制ignoredbutsave屬性。 我嘗試使用xsl:param從XPath中選擇屬性名稱,並在xsl:attribute中使用它,如下所示:

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

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

  <xsl:template match="/EntityA/EntityB/@id">
    <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
       <xsl:param name="newValue" select="name(/EntityA/EntityB/@id)"/>
         <xsl:attribute name="$newValue">newAttributeId</xsl:attribute>
     </xsl:copy>
  </xsl:template>

  <xsl:template match="/EntityA/EntityB/@value">
    <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
       <xsl:param name="myattrname" select="name(/EntityA/EntityB/@value)"/>
         <xsl:attribute name="$myattrname">newAttributeValue</xsl:attribute>
     </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

但是,這會導致錯誤The value '$myattrname' of the attribute 'name' is not a valid QName.

因此,為問題提供了一個屬性的XPath和該屬性的新值,我如何生成一個XSLT來更新該值而無需顯式引用屬性名?

此XSLT轉換:

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

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

  <xsl:template match="/EntityA/EntityB/@id">
    <xsl:attribute name="{name()}">foo2</xsl:attribute>
  </xsl:template>

  <xsl:template match="/EntityA/EntityB/@value">
    <xsl:attribute name="{name()}">bar2</xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

應用於您的舊XML:

<EntityA>
  <EntityB id="foo1" value="bar1" ignoredbutsave="bazz1"/>
</EntityA>

使用所需的屬性值替換產生舊的XML:

<EntityA>
  <EntityB id="foo2" value="bar2" ignoredbutsave="bazz1"/>
</EntityA>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM