Изменить атрибут определенных элементов XML - PullRequest
3 голосов
/ 10 июня 2010

Я хотел бы изменить атрибут очень длинного xml следующим образом:

<element index="0">
    <subelement bla="asdf" />
    <subelement bla="asdf" />
</element>
<element index="1">
    <subelement bla="asdf" />
    <subelement bla="asdf" />
</element>
...

Мне нужно добавить N значение каждого атрибута индекса. Скажите N = 5. Результат будет:

<element index="5">
    <subelement bla="asdf" />
    <subelement bla="asdf" />
</element>
<element index="6">
    <subelement bla="asdf" />
    <subelement bla="asdf" />
</element>
...

Какой самый простой способ сделать это? Я предполагаю, что это будет с XSLT, но я не знаю, как это сделать.

Спасибо!

Ответы [ 3 ]

4 голосов
/ 10 июня 2010
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes"/>

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

  <!-- except "element" nodes -->
  <xsl:template match="element">
    <xsl:copy>
      <xsl:attribute name="index">
        <xsl:value-of select="@index + 5"/>
      </xsl:attribute>
      <xsl:apply-templates />
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
3 голосов
/ 10 июня 2010

svick ответ, это хорошее решение. На всякий случай, если вам нужно сохранить точную структуру, попробуйте:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:param name="increment" select="5" />

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

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

<xsl:template match="element/@index">
 <xsl:attribute name="index">
  <xsl:value-of select="$increment + ." />
 </xsl:attribute>
</xsl:template>

</xsl:stylesheet>
0 голосов
/ 14 декабря 2016

Вот несколько общее решение для увеличения произвольного атрибута:

#!/bin/bash

PROG=$(basename $0 )
: ${TMPDIR:=/tmp}
:  ${INC:=1}
TMPFILE=$TMPDIR/$PROG.$$.xml

function usage() {

cat <<!
$PROG <attribute>  <input-xml>

Increases all attributes named <attribute> in the <input-xml> XML file by 1 ( or \$INC ) 
!
exit 1
}

[ $# -eq 2 ] || usage

{
cat <<!
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes"/>

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

  <!-- except "attribute-of-interest" node -->
  <xsl:template match="@$1">
    <xsl:attribute name="$1">
        <xsl:value-of select=". + $INC"/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>
!
}  xsltproc /dev/stdin $2 > $TMPFILE  && mv $TMPFILE $2

Очевидно, что это ответ svick.Я немного изменил XSL, чтобы охватить несколько атрибутов в целевом элементе.FWIW, я шаблонизировал это, используя bash.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...