1

次の XML ファイルがあるとします。

<a>前<b>中</b>後</a>

私はそれを次のようなものに変換したい:

<a>前中後</a>

つまり、特定のノードのすべての子ノードを取得し、それらを親ノードに順番に移動したいと考えています。これは、「mv ./directory/* .」というコマンドを実行するのと似ていますが、xml ノードの場合です。

UNIXコマンドラインツールを使用してこれを行いたいです。私は、強力なコマンドライン XML マニピュレーターである xmlstarlet を試してきました。私はこのようなことをしてみましたが、うまくいきません

echo "<a>前<b>中</b>後</a>" | xmlstarlet ed -m "//b/*" ".."

更新: XSLT テンプレートは、コマンド ラインから呼び出すことができるため、問題ありません。

ここでの私の目標は、「XHTML ページからリンクを削除する」ことです。つまり、リンクがあった場所を link タグのコンテンツに置き換えます。

4

5 に答える 5

3

入力ファイルの例 (test.xml):

<?xml version="1.0" encoding="UTF-8"?>
<test>
<x>before<y>middle</y>after</x>
<a>before<b>middle</b>after</a>
<a>before<b>middle</b>after</a>
<x>before<y>middle</y>after</x>
<a>before<b>middle</b>after</a>
<embedded>foo<a>before<b>middle</b>after</a>bar</embedded>
</test>

XSLT スタイルシート (collapse.xsl:

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

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

      <xsl:template match="a">
        <xsl:copy>
          <xsl:value-of select="."/>
        </xsl:copy>
      </xsl:template>

    </xsl:stylesheet>

を使用してXmlStarletで実行します

xml tr collapse.xsl test.xml

プロデュース:

<?xml version="1.0"?>
<test>
<x>before<y>middle</y>after</x>
<a>beforemiddleafter</a>
<a>beforemiddleafter</a>
<x>before<y>middle</y>after</x>
<a>beforemiddleafter</a>
<embedded>foo<a>beforemiddleafter</a>bar</embedded>
</test>

スタイルシートの最初のテンプレートは、基本的な恒等変換です (入力 XML ドキュメント全体をコピーするだけです)。2 番目のテンプレートは、「折りたたみ」たい要素に明確に一致し、タグをコピーして要素の文字列値を挿入するだけです (= 子孫ノードの文字列値の連結)。

于 2008-09-24T05:22:55.783 に答える
2

実際の目標が Web ページからリンクを削除することである場合は、次のようなスタイルシートを使用する必要があります。これは、すべての XHTML<a>要素に一致し (XHTML を使用していると思いますか?)、単純にテンプレートをコンテンツに適用します。

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:h="http://www.w3.org/1999/xhtml"
  exclude-result-prefixes="h">

<!-- Don't copy the <a> elements, just process their content -->
<xsl:template match="h:a">
  <xsl:apply-templates />
</xsl:template>

<!-- identity template; copies everything by default -->
<xsl:template match="node()|@*">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()" />
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

このスタイルシートは、次のように、保持したい要素に何かがネストされている状況に対処します。<a>

<p>Here is <a href="....">some <em>linked</em> text</a>.</p>

あなたは次のように出てきたいと思うでしょう:

<p>Here is some <em>linked</em> text.</p>

<p>また、次のような、通常の親 (要素) と要素の間の予期しない要素内にリンクがネストされている状況に対処します<a>

<p>Here is <em>some <a href="...">linked</a> text</em>.</p>
于 2008-09-25T08:44:15.713 に答える
2

XSLT では、次のように記述できます。

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

<xsl:template match="a/b"><xsl:value-of select="."/></xsl:template>

そして、あなたは得るでしょう:

<a>beforemiddleafter</a>

したがって、これを簡単に実行したい場合は、XSL スタイルシートを作成し、それを介して XML ファイルを実行するだけです。

ただし、これはあなたがやりたいと言ったことではありません(Unixコマンドラインを使用)。私は Unix について何も知らないので、他の誰かが空欄を埋めることができるかもしれません。上記を実行できるある種のコマンドライン呼び出し。

于 2008-09-23T22:04:31.080 に答える
1

xmlstarlet の使用:

xmlstr='<a>before<b>middle</b>after</a>'
updatestr="$(echo "$xmlstr" | xmlstarlet sel -T -t -m "/a/b" -v '../.' -n | sed -n '1{p;q;}')"
echo "$xmlstr" | xmlstarlet ed -u "/a" -v "$updatestr"
于 2010-07-04T07:55:36.513 に答える
0

これを試しましたか?

file.xml

<r>
    <a>start<b>middle</b>end</a>
</r>

template.xsl

<xsl:template match="/">
    <a><xsl:value-of select="r/a" /></a>
</xsl:template>

output

<a>startmiddleend</a>
于 2008-09-24T13:50:06.283 に答える