浏览代码

The get and set methods for Paragraph.Hyperlinks where broken.

This changeset fixes that and another issue. I discovered that Word allows Hyperlinks to be defined in two ways, inline and normal. DocX now supports both.
This changeset also contains new unit tests that will hopefully prevent Hyperlink support from braking again.
master
coffeycathal_cp 14 年前
父节点
当前提交
4d238d3c93
共有 4 个文件被更改,包括 229 次插入51 次删除
  1. 3
    3
      DocX/DocX.cs
  2. 84
    42
      DocX/Hyperlink.cs
  3. 51
    6
      DocX/Paragraph.cs
  4. 91
    0
      UnitTests/UnitTest1.cs

+ 3
- 3
DocX/DocX.cs 查看文件

@@ -1819,10 +1819,10 @@ namespace Novacode
new XElement(XName.Get("t", DocX.w.NamespaceName), text))
);
Hyperlink h = new Hyperlink(this, i);
Hyperlink h = new Hyperlink(this, mainPart, i);
h.Text = text;
h.Uri = uri;
h.text = text;
h.uri = uri;
AddHyperlinkStyleIfNotPresent();

+ 84
- 42
DocX/Hyperlink.cs 查看文件

@@ -13,7 +13,13 @@ namespace Novacode
public class Hyperlink: DocXElement
{
internal Uri uri;
internal String text;
internal Dictionary<PackagePart, PackageRelationship> hyperlink_rels;
public PackagePart mainPart;
internal int type;
internal String id;
internal XElement instrText;
/// <summary>
/// Remove a Hyperlink from this Paragraph only.
@@ -75,46 +81,45 @@ namespace Novacode
{
get
{
// Create a string builder.
StringBuilder sb = new StringBuilder();
// Get all the runs in this Text.
var runs = from r in Xml.Elements()
where r.Name.LocalName == "r"
select new Run(Document, r, 0);
// Remove each run.
foreach (Run r in runs)
sb.Append(r.Value);
return sb.ToString();
return this.text;
}
set
{
// Get all the runs in this Text.
var runs = from r in Xml.Elements()
where r.Name.LocalName == "r"
select r;
// Remove each run.
for (int i = 0; i < runs.Count(); i++)
runs.Remove();
XElement rPr =
new XElement
(
DocX.w + "rPr",
XElement rPr =
new XElement
(
DocX.w + "rStyle",
new XAttribute(DocX.w + "val", "Hyperlink")
)
);
DocX.w + "rPr",
new XElement
(
DocX.w + "rStyle",
new XAttribute(DocX.w + "val", "Hyperlink")
)
);
// Format and add the new text.
List<XElement> newRuns = HelperFunctions.FormatInput(value, rPr);
Xml.Add(newRuns);
if (type == 0)
{
// Get all the runs in this Text.
var runs = from r in Xml.Elements()
where r.Name.LocalName == "r"
select r;
// Remove each run.
for (int i = 0; i < runs.Count(); i++)
runs.Remove();
Xml.Add(newRuns);
}
else
{
Xml.ReplaceWith(newRuns);
}
this.text = value;
}
}
@@ -143,34 +148,71 @@ namespace Novacode
public Uri Uri
{
get
{
// Return the Hyperlinks Uri.
return uri;
{
if (type == 0 && id != String.Empty)
{
PackageRelationship r = mainPart.GetRelationship(id);
return r.TargetUri;
}
return this.uri;
}
set
{
foreach (PackagePart p in hyperlink_rels.Keys)
if (type == 0)
{
PackageRelationship r = hyperlink_rels[p];
PackageRelationship r = mainPart.GetRelationship(id);
// Get all of the information about this relationship.
TargetMode r_tm = r.TargetMode;
string r_rt = r.RelationshipType;
string r_id = r.Id;
// Delete the relationship
p.DeleteRelationship(r_id);
p.CreateRelationship(value, r_tm, r_rt, r_id);
mainPart.DeleteRelationship(r_id);
mainPart.CreateRelationship(value, r_tm, r_rt, r_id);
}
else
{
instrText.Value = "HYPERLINK " + "\"" + value + "\"";
}
uri = value;
this.uri = value;
}
}
internal Hyperlink(DocX document, XElement i): base(document, i)
internal Hyperlink(DocX document, PackagePart mainPart, XElement i): base(document, i)
{
hyperlink_rels = new Dictionary<PackagePart, PackageRelationship>();
this.type = 0;
this.id = i.Attribute(XName.Get("id", DocX.r.NamespaceName)).Value;
StringBuilder sb = new StringBuilder();
HelperFunctions.GetTextRecursive(i, ref sb);
this.text = sb.ToString();
}
internal Hyperlink(DocX document, XElement instrText, XElement r) : base(document, r)
{
this.type = 1;
this.instrText = instrText;
try
{
int start = instrText.Value.IndexOf("HYPERLINK \"") + "HYPERLINK \"".Length;
int end = instrText.Value.IndexOf("\"", start);
if (start != -1 && end != -1)
{
this.uri = new Uri(instrText.Value.Substring(start, end - start), UriKind.Absolute);
StringBuilder sb = new StringBuilder();
HelperFunctions.GetTextRecursive(r, ref sb);
this.text = sb.ToString();
}
}
catch (Exception e){throw e;}
}
}
}

+ 51
- 6
DocX/Paragraph.cs 查看文件

@@ -101,13 +101,58 @@ namespace Novacode
{
get
{
List<Hyperlink> hyperlinks =
List<Hyperlink> hyperlinks = new List<Hyperlink>();
List<XElement> hyperlink_elements =
(
from h in Xml.Elements()
where (h.Name.LocalName == "hyperlink")
select new Hyperlink(Document, h)
from h in Xml.Descendants()
where (h.Name.LocalName == "hyperlink" || h.Name.LocalName == "instrText")
select h
).ToList();
foreach (XElement he in hyperlink_elements)
{
if (he.Name.LocalName == "hyperlink")
{
try
{
Hyperlink h = new Hyperlink(Document, mainPart, he);
h.mainPart = mainPart;
hyperlinks.Add(h);
}
catch (Exception) { }
}
else
{
// Find the parent run, no matter how deeply nested we are.
XElement e = he;
while (e.Name.LocalName != "r")
e = e.Parent;
foreach (XElement r in e.ElementsAfterSelf(XName.Get("r", DocX.w.NamespaceName)))
{
XElement rStyle = r.Descendants(XName.Get("rStyle", DocX.w.NamespaceName)).SingleOrDefault<XElement>();
if (rStyle != null)
{
XAttribute a = rStyle.Attribute(XName.Get("val", DocX.w.NamespaceName));
if (a != null && a.Value.Equals("Hyperlink", StringComparison.CurrentCultureIgnoreCase))
{
try
{
Hyperlink h = new Hyperlink(Document, he, r);
h.mainPart = mainPart;
hyperlinks.Add(h);
}
catch(Exception){}
}
}
}
}
}
return hyperlinks;
}
}
@@ -1968,7 +2013,7 @@ namespace Novacode
if (!Document.package.PartExists(rels_path))
HelperFunctions.CreateRelsPackagePart(Document, rels_path);
// Check to see if a rel for this Picture exists, create it if not.
// Check to see if a rel for this Hyperlink exists, create it if not.
var Id = GetOrGenerateRel(h);
Xml.Add(h.Xml);

+ 91
- 0
UnitTests/UnitTest1.cs 查看文件

@@ -548,6 +548,97 @@ namespace UnitTests
}
}
[TestMethod]
public void Test_Get_Set_Hyperlink()
{
// Load test document.
using (DocX document = DocX.Load(directory_documents + "Hyperlinks.docx"))
{
// Hyperlinks in the document.
Assert.IsTrue(document.Hyperlinks.Count == 3);
Assert.IsTrue(document.Hyperlinks[0].Text == "page1");
Assert.IsTrue(document.Hyperlinks[0].Uri.AbsoluteUri == "http://www.page1.com/");
Assert.IsTrue(document.Hyperlinks[1].Text == "page2");
Assert.IsTrue(document.Hyperlinks[1].Uri.AbsoluteUri == "http://www.page2.com/");
Assert.IsTrue(document.Hyperlinks[2].Text == "page3");
Assert.IsTrue(document.Hyperlinks[2].Uri.AbsoluteUri == "http://www.page3.com/");
// Change the Hyperlinks and check that it has in fact changed.
document.Hyperlinks[0].Text = "somethingnew";
document.Hyperlinks[0].Uri = new Uri("http://www.google.com/");
Assert.IsTrue(document.Hyperlinks[0].Text == "somethingnew");
Assert.IsTrue(document.Hyperlinks[0].Uri.AbsoluteUri == "http://www.google.com/");
document.Hyperlinks[1].Text = "somethingnew";
document.Hyperlinks[1].Uri = new Uri("http://www.google.com/");
Assert.IsTrue(document.Hyperlinks[1].Text == "somethingnew");
Assert.IsTrue(document.Hyperlinks[1].Uri.AbsoluteUri == "http://www.google.com/");
document.Hyperlinks[2].Text = "somethingnew";
document.Hyperlinks[2].Uri = new Uri("http://www.google.com/");
Assert.IsTrue(document.Hyperlinks[2].Text == "somethingnew");
Assert.IsTrue(document.Hyperlinks[2].Uri.AbsoluteUri == "http://www.google.com/");
Assert.IsTrue(document.Headers.first.Hyperlinks.Count == 1);
Assert.IsTrue(document.Headers.first.Hyperlinks[0].Text == "header-first");
Assert.IsTrue(document.Headers.first.Hyperlinks[0].Uri.AbsoluteUri == "http://www.header-first.com/");
// Change the Hyperlinks and check that it has in fact changed.
document.Headers.first.Hyperlinks[0].Text = "somethingnew";
document.Headers.first.Hyperlinks[0].Uri = new Uri("http://www.google.com/");
Assert.IsTrue(document.Headers.first.Hyperlinks[0].Text == "somethingnew");
Assert.IsTrue(document.Headers.first.Hyperlinks[0].Uri.AbsoluteUri == "http://www.google.com/");
Assert.IsTrue(document.Headers.odd.Hyperlinks.Count == 1);
Assert.IsTrue(document.Headers.odd.Hyperlinks[0].Text == "header-odd");
Assert.IsTrue(document.Headers.odd.Hyperlinks[0].Uri.AbsoluteUri == "http://www.header-odd.com/");
// Change the Hyperlinks and check that it has in fact changed.
document.Headers.odd.Hyperlinks[0].Text = "somethingnew";
document.Headers.odd.Hyperlinks[0].Uri = new Uri("http://www.google.com/");
Assert.IsTrue(document.Headers.odd.Hyperlinks[0].Text == "somethingnew");
Assert.IsTrue(document.Headers.odd.Hyperlinks[0].Uri.AbsoluteUri == "http://www.google.com/");
Assert.IsTrue(document.Headers.even.Hyperlinks.Count == 1);
Assert.IsTrue(document.Headers.even.Hyperlinks[0].Text == "header-even");
Assert.IsTrue(document.Headers.even.Hyperlinks[0].Uri.AbsoluteUri == "http://www.header-even.com/");
// Change the Hyperlinks and check that it has in fact changed.
document.Headers.even.Hyperlinks[0].Text = "somethingnew";
document.Headers.even.Hyperlinks[0].Uri = new Uri("http://www.google.com/");
Assert.IsTrue(document.Headers.even.Hyperlinks[0].Text == "somethingnew");
Assert.IsTrue(document.Headers.even.Hyperlinks[0].Uri.AbsoluteUri == "http://www.google.com/");
Assert.IsTrue(document.Footers.first.Hyperlinks.Count == 1);
Assert.IsTrue(document.Footers.first.Hyperlinks[0].Text == "footer-first");
Assert.IsTrue(document.Footers.first.Hyperlinks[0].Uri.AbsoluteUri == "http://www.footer-first.com/");
// Change the Hyperlinks and check that it has in fact changed.
document.Footers.first.Hyperlinks[0].Text = "somethingnew";
document.Footers.first.Hyperlinks[0].Uri = new Uri("http://www.google.com/");
Assert.IsTrue(document.Footers.first.Hyperlinks[0].Text == "somethingnew");
Assert.IsTrue(document.Footers.first.Hyperlinks[0].Uri.AbsoluteUri == "http://www.google.com/");
Assert.IsTrue(document.Footers.odd.Hyperlinks.Count == 1);
Assert.IsTrue(document.Footers.odd.Hyperlinks[0].Text == "footer-odd");
Assert.IsTrue(document.Footers.odd.Hyperlinks[0].Uri.AbsoluteUri == "http://www.footer-odd.com/");
// Change the Hyperlinks and check that it has in fact changed.
document.Footers.odd.Hyperlinks[0].Text = "somethingnew";
document.Footers.odd.Hyperlinks[0].Uri = new Uri("http://www.google.com/");
Assert.IsTrue(document.Footers.odd.Hyperlinks[0].Text == "somethingnew");
Assert.IsTrue(document.Footers.odd.Hyperlinks[0].Uri.AbsoluteUri == "http://www.google.com/");
Assert.IsTrue(document.Footers.even.Hyperlinks.Count == 1);
Assert.IsTrue(document.Footers.even.Hyperlinks[0].Text == "footer-even");
Assert.IsTrue(document.Footers.even.Hyperlinks[0].Uri.AbsoluteUri == "http://www.footer-even.com/");
// Change the Hyperlinks and check that it has in fact changed.
document.Footers.even.Hyperlinks[0].Text = "somethingnew";
document.Footers.even.Hyperlinks[0].Uri = new Uri("http://www.google.com/");
Assert.IsTrue(document.Footers.even.Hyperlinks[0].Text == "somethingnew");
Assert.IsTrue(document.Footers.even.Hyperlinks[0].Uri.AbsoluteUri == "http://www.google.com/");
}
}
[TestMethod]
public void Test_Append_Hyperlink()
{

正在加载...
取消
保存