14

いくつかの XML データ (以下のサンプルに似ています) があり、コードで値を読み取りたいと考えています。

各要素にアクセスするためにデフォルトの名前空間を指定しなければならないのはなぜですか? すべての要素にデフォルトの名前空間が使用されることを期待していました。

私の目標を達成するためのより論理的な方法はありますか?

サンプル XML:

<?xml version="1.0" encoding="UTF-8"?>
<ReceiptsBatch xmlns="http://www.secretsonline.gov.uk/secrets">
    <MessageHeader>
        <MessageID>00000173</MessageID>
        <Timestamp>2009-10-28T16:50:01</Timestamp>
        <MessageCheck>BX4f+RmNCVCsT5g</MessageCheck>
    </MessageHeader>
    <Receipts>
        <Receipt>
            <Status>OK</Status>
        </Receipt>
    </Receipts>
</ReceiptsBatch>

私が求めているxml要素を読み取るためのコード:

XDocument xDoc = XDocument.Load( FileInPath );

XNamespace ns = "http://www.secretsonline.gov.uk/secrets";

XElement MessageCheck = xDoc.Element(ns+ "MessageHeader").Element(ns+"MessageCheck");
XElement MessageBody = xDoc.Element("Receipts");
4

5 に答える 5

9

この回答で示唆されているように、ドキュメントのメモリ内コピーからすべての名前空間を削除することでこれを行うことができます。結果のドキュメントに名前の衝突がないことがわかっている場合にのみ、これを行う必要があると思います。

/// <summary>
/// Makes parsing easier by removing the need to specify namespaces for every element.
/// </summary>
private static void RemoveNamespaces(XDocument document)
{
    var elements = document.Descendants();
    elements.Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
    foreach (var element in elements)
    {
        element.Name = element.Name.LocalName;

        var strippedAttributes =
            from originalAttribute in element.Attributes().ToArray()
            select (object)new XAttribute(originalAttribute.Name.LocalName, originalAttribute.Value);

        //Note that this also strips the attributes' line number information
        element.ReplaceAttributes(strippedAttributes.ToArray());
    }
}
于 2013-08-29T06:16:29.227 に答える
6

XmlTextReader.Namespacesプロパティを使用して、XML ファイルの読み取り中に名前空間を無効にすることができます。

string filePath;
XmlTextReader xReader = new XmlTextReader(filePath);
xReader.Namespaces = false;
XDocument xDoc = XDocument.Load(xReader);
于 2016-11-28T12:48:36.373 に答える
3

これが Linq-To-Xml の仕組みです。デフォルトの名前空間にない場合、要素を見つけることができず、その子孫についても同じことが言えます。名前空間を削除する最も簡単な方法は、最初の XML から名前空間へのリンクを削除することです。

于 2011-09-12T11:26:23.770 に答える
1

理論は、ドキュメントの意味は、ユーザーが名前空間プレフィックスを選択することによって影響を受けないというものです。データが名前空間http://www.secretsonline.gov.uk/secretsにある限り、作成者がプレフィックス「s」、「secrets」、「_x.cafe.babe」を使用することを選択したかどうかは関係ありません。 "、または" null "プレフィックス(つまり、デフォルトの名前空間にします)。アプリケーションは気にする必要はありません。重要なのはURIだけです。そのため、アプリケーションでURIを指定する必要があります。

于 2011-09-12T14:15:40.557 に答える
1

Receipts要素は namespacehttp://www.secretsonline.gov.uk/secretsにもあることに注意してください。そのためXNamespace、要素へのアクセスには も必要になります。

XElement MessageBody = xDoc.Element(ns + "Receipts");

名前空間を使用する代わりに、local-name()andを使用して「名前空間に依存しない」xpath を使用できることに注意してください。namespace-uri()

/*[local-name()='SomeElement' and namespace-uri()='somexmlns']

namespace-uri述語を省略した場合:

/*[local-name()='SomeElement']

一致するns1:SomeElementなどns2:SomeElement。IMOは可能な限り常に好みXNamespaceます。名前空間に依存しないxpathのユースケースは非常に限られています。たとえば、スキーマが不明なドキュメント(サービスバス内など)の特定の要素の解析、またはベストエフォート名前空間が変更される可能性があるドキュメントの解析 (たとえばxmlns、ドキュメント スキーマの新しいバージョンに合わせて変更が行われる将来の校正)

于 2011-09-12T11:28:40.433 に答える