【问题标题】:How to avoid xmlns="" in an XML-element added?如何在添加的 XML 元素中避免 xmlns=""?
【发布时间】:2013-12-03 04:35:57
【问题描述】:

我有 287 个 SSRS 报告(XML 文件),我需要在其中添加一个参数。
他们都是这样开始的:

<?xml version="1.0" encoding="utf-8"?>
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
<DataSources>
<DataSource Name="COR_Basic">
<rd:DataSourceID>addde073-f37c-4b59-ae3a-25231ffc0ec6</rd:DataSourceID>
<DataSourceReference>COR_Basic</DataSourceReference>
</DataSource>
</DataSources>
<InteractiveHeight>29.7cm</InteractiveHeight>
<ReportParameters>
<ReportParameter Name="in_report_name">
<DataType>String</DataType>
<DefaultValue>
<Values>
<Value>=Globals!ReportName</Value>
</Values>
</DefaultValue>
<Prompt>Report Name</Prompt>
<Hidden>true</Hidden>
</ReportParameter>
<ReportParameter Name="in_mandant">
<DataType>String</DataType>
<DefaultValue>
<Values>
<Value>0</Value>
</Values>
</DefaultValue>
<Prompt>in_mandant</Prompt>
<Hidden>true</Hidden>
</ReportParameter>

现在我想自动将“proc”参数添加到所有报告中。
这意味着我需要插入这段 XML

<ReportParameter Name="proc">
<DataType>String</DataType>
<DefaultValue>
<Values>
<Value>MyTestValue</Value>
</Values>
</DefaultValue>
<Prompt>MyPromptText</Prompt>
<Hidden>true</Hidden>
</ReportParameter>

之后

<ReportParameter Name="in_mandant">
...
</ReportParameter>

这是我目前的代码:

public static System.Xml.XmlDocument File2XmlDocument(string strFileName)
{
    // http://blogs.msdn.com/b/tolong/archive/2007/11/15/read-write-xml-in-memory-stream.aspx
    System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
    // doc.Load(memorystream);
    // doc.Load(FILE_NAME);

    using (System.Xml.XmlTextReader xtrReader = new System.Xml.XmlTextReader(strFileName))
    {

        doc.Load(xtrReader);
        xtrReader.Close();
    } // End Using xtrReader

    return doc;
} // End Function File2XmlDocument




        public static System.Xml.XmlNamespaceManager GetReportNamespaceManager(System.Xml.XmlDocument doc)
        {
            System.Xml.XmlNamespaceManager nsmgr = new System.Xml.XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("dft", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");

            return nsmgr;
        } // End Function GetReportNamespaceManager



 public static void AddProc(string strFilename)
        {
            System.Xml.XmlDocument doc = File2XmlDocument(strFilename);
            System.Xml.XmlElement root = doc.DocumentElement;
            System.Xml.XmlNamespaceManager nsmgr = GetReportNamespaceManager(doc);

            System.Xml.XmlNode xnMandant = root.SelectSingleNode("/dft:Report/dft:ReportParameters/dft:ReportParameter[@Name=\"in_mandant\"]", nsmgr);

            string strReportName = System.IO.Path.GetFileNameWithoutExtension(strFilename);

            if (xnMandant != null)
            {
                LogMessage("{0}\t{1}", strReportName, xnMandant.FirstChild.Value);

                string frag = @"<ReportParameter Name=""proc"">
<DataType>String</DataType>
<DefaultValue>
<Values>
<Value>MyTestValue</Value>
</Values>
</DefaultValue>
<Prompt>MyPromptText</Prompt>
<Hidden>true</Hidden>
</ReportParameter>";

                System.Xml.XmlDocumentFragment xmlDocFrag = doc.CreateDocumentFragment();
                xmlDocFrag.InnerXml = frag;

                System.Xml.XmlNode xn = xnMandant.ParentNode.InsertAfter(xmlDocFrag, xnMandant);

                Console.WriteLine(xn.OuterXml);

            }
            else
                LogMessage("{0}\tKein Parameter in_mandant", strReportName);


            SaveDocument(doc, strFilename);
        } // End Sub PrintStichtag

这会在正确的位置插入 XML 片段,但我在 "proc" 之后有一个 xmlns=""

<ReportParameter Name="proc" xmlns="">
<DataType>String</DataType>
<DefaultValue>
<Values>
<Value>MyTestValue</Value>
</Values>
</DefaultValue>
<Prompt>MyPromptText</Prompt>
<Hidden>true</Hidden>
</ReportParameter>

如何避免空的 xmlns 属性?
(缺少将 xml 文件作为文本加载并执行 string.replace)。

【问题讨论】:

    标签: c# .net xml xml-namespaces xmldocument


    【解决方案1】:

    如何避免空的 xmlns 属性?

    在正确的命名空间中创建元素。由于namespace defaulting所有你的元素应该在http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition命名空间中。

    您可以尝试插入片段并然后设置其 InnerXml 值 - 这可能会适当地应用命名空间默认值。

    然而,就我个人而言,我会使用 LINQ to XML,这使得命名空间处理变得非常简单 - 然后以编程方式构造元素,而不是从文本中解析它们。实际上,无论如何我都会以编程方式构造元素,而不是设置 InnerXml - 这样可以更轻松地精确控制命名空间等内容,因为您可以在构造元素时指定它们。

    (我还强烈建议使用 using 指令,以避免您的代码到处都充满完全限定名称。)

    【讨论】:

    • @Quandary:老鼠,没发现。在这种情况下,您可以在设置 InnerXml 片段之前尝试添加它,但老实说,您最好以编程方式创建它。
    • 那也行不通。不过还是谢谢。顺便说一句,我不能使用 LINQ,我们仍在使用 .NET 2.0...
    【解决方案2】:

    这似乎根本不可能(“感谢”只读属性)。
    唯一的解决方法是替换文档的 OuterXml,然后重新加载文档。

        public static void SaveDocument(System.Xml.XmlDocument doc, string strFilename, bool bDoReplace)
        {
            string strSavePath = GetSavePath();
            strSavePath = System.IO.Path.Combine(strSavePath, System.IO.Path.GetFileName(strFilename));
    
            if (bDoReplace)
            {
                doc.LoadXml(doc.OuterXml.Replace("xmlns=\"\"", ""));
                // doc.LoadXml(doc.OuterXml.Replace(strTextToReplace, strReplacementText));
            }
    
            using (System.Xml.XmlTextWriter xtw = new System.Xml.XmlTextWriter(strSavePath, System.Text.Encoding.UTF8))
            {
                xtw.Formatting = System.Xml.Formatting.Indented; // if you want it indented
                xtw.Indentation = 4;
                xtw.IndentChar = ' ';
    
                doc.Save(xtw);
            } // End Using xtw
    
        } // End Sub SaveDocument
    

    【讨论】:

    • 这应该使用新的 XmlWriter。享受这种无格式的混乱:) var xmlConfig = new XmlWriterSettings(){Indent = true, IndentChars = " ", Encoding = System.Text.Encoding.UTF8};使用 (XmlWriter xw = XmlWriter.Create(strSavePath, xmlConfig)){ doc.Save(xw); }
    【解决方案3】:

    在添加时使用此命名空间并进行以下设置。

         XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
         namespaces.Add(string.Empty, string.Empty);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-01
      • 1970-01-01
      • 2011-04-05
      • 2019-10-21
      • 2020-10-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多